morpheus.PcaPlotTool = function (chartOptions) {
    var _this = this;
    this.project = chartOptions.project;
    var project = this.project;


    this.$el = $('<div class="container-fluid">'
        + '<div class="row">'
        + '<div data-name="configPane" class="col-xs-2"></div>'
        + '<div class="col-xs-10"><div style="position:relative;" data-name="chartDiv"></div></div>'
        + '</div></div>');

    var formBuilder = new morpheus.FormBuilder({
        vertical: true
    });
    this.formBuilder = formBuilder;
    var rowOptions = [];
    var columnOptions = [];
    var numericRowOptions = [];
    var numericColumnOptions = [];
    var options = [];
    var numericOptions = [];
    var updateOptions = function () {
        var dataset = project.getFullDataset();
        rowOptions = [{
            name: '(None)',
            value: ''
        }];
        columnOptions = [{
            name: '(None)',
            value: ''
        }];
        numericRowOptions = [{
            name: '(None)',
            value: ''
        }];
        numericColumnOptions = [{
            name: '(None)',
            value: ''
        }];
        options = [{
            name: '(None)',
            value: ''
        }];
        numericOptions = [{
            name: '(None)',
            value: ''
        }];

        morpheus.MetadataUtil.getMetadataNames(dataset.getRowMetadata())
            .forEach(
                function (name) {
                    var dataType = morpheus.VectorUtil
                        .getDataType(dataset.getRowMetadata()
                            .getByName(name));
                    if (dataType === 'number'
                        || dataType === '[number]') {
                        numericRowOptions.push({
                            name: name + ' (row)',
                            value: name
                        });
                    }
                    rowOptions.push({
                        name: name + ' (row)',
                        value: name
                    });
                });

        morpheus.MetadataUtil.getMetadataNames(dataset.getColumnMetadata())
            .forEach(
                function (name) {
                    var dataType = morpheus.VectorUtil
                        .getDataType(dataset.getColumnMetadata()
                            .getByName(name));
                    if (dataType === 'number'
                        || dataType === '[number]') {
                        numericColumnOptions.push({
                            name: name + ' (column)',
                            value: name
                        });
                    }
                    columnOptions.push({
                        name: name + ' (column)',
                        value: name
                    });
                });

        options = options.concat(rowOptions.slice(1));
        options = options.concat(columnOptions.slice(1));

        numericOptions = numericOptions.concat(numericRowOptions.slice(1));
        numericOptions = numericOptions.concat(numericColumnOptions.slice(1));
    };

    updateOptions();

    formBuilder.append({
        name: 'group_columns_by',
        type: 'bootstrap-select',
        options: options
    });
    formBuilder.append({
        name: 'group_rows_by',
        type: 'bootstrap-select',
        options: options
    });

    formBuilder.append({
        name: 'size',
        type: 'bootstrap-select',
        options: numericOptions
    });
    formBuilder.append({
        name: 'color',
        type: 'bootstrap-select',
        options: numericOptions
    });


    function setVisibility() {
        formBuilder.setOptions('color', options, true);
        formBuilder.setOptions('size', numericOptions, true);
    }

    this.tooltip = [];
    formBuilder.$form.find('select').on('change', function (e) {
        if ($(this).attr('name') === 'tooltip') {
            var tooltipVal = _this.formBuilder.getValue('tooltip');
            _this.tooltip = [];
            if (tooltipVal != null) {
                tooltipVal.forEach(function (tip) {
                    _this.tooltip.push(morpheus.ChartTool.getVectorInfo(tip));
                });
            }
        } else {
            setVisibility();
            _this.draw();
        }

    });
    formBuilder.$form.find('input').on('click', function () {
        _this.draw();
    });
    setVisibility();

    var draw = function () {
        _.debounce(_this.draw(), 100);
    };
    var trackChanged = function () {
        updateOptions();
        setVisibility();
        formBuilder.setOptions('group_columns_by', options, true);
        formBuilder.setOptions('group_rows_by', options, true);
    };

    project.getColumnSelectionModel().on('selectionChanged.chart', draw);
    project.getRowSelectionModel().on('selectionChanged.chart', draw);
    project.on('trackChanged.chart', trackChanged);
    this.$chart = this.$el.find('[data-name=chartDiv]');
    var $dialog = $('<div style="background:white;" title="Chart"></div>');
    var $configPane = this.$el.find('[data-name=configPane]');
    formBuilder.$form.appendTo($configPane);
    this.$el.appendTo($dialog);
    $dialog.dialog({
        close: function (event, ui) {
            project.off('trackChanged.chart', trackChanged);
            project.getRowSelectionModel().off('selectionChanged.chart', draw);
            project.getColumnSelectionModel().off('selectionChanged.chart',
                draw);
            _this.$el.empty();
        },

        resizable: true,
        height: 600,
        width: 900
    });
    this.$dialog = $dialog;
    this.draw();



};

morpheus.PcaPlotTool.getVectorInfo = function (value) {
    var field = value.substring(0, value.length - 2);
    var isColumns = value.substring(value.length - 2) === '_c';
    return {
        field: field,
        isColumns: isColumns
    };
};
morpheus.PcaPlotTool.prototype = {
    annotate: function (options) {
        var _this = this;
        var formBuilder = new morpheus.FormBuilder();
        formBuilder.append({
            name: 'annotation_name',
            type: 'text',
            required: true
        });
        formBuilder.append({
            name: 'annotation_value',
            type: 'text',
            required: true
        });
        morpheus.FormBuilder
            .showOkCancel({
                title: 'Annotate Selection',
                content: formBuilder.$form,
                okCallback: function () {
                    var dataset = options.dataset;
                    var eventData = options.eventData;
                    var array = options.array;
                    var value = formBuilder.getValue('annotation_value');
                    var annotationName = formBuilder
                        .getValue('annotation_name');
                    // var annotate = formBuilder.getValue('annotate');
                    var isRows = true;
                    var isColumns = true;
                    var existingRowVector = null;
                    var rowVector = null;
                    if (isRows) {
                        existingRowVector = dataset.getRowMetadata()
                            .getByName(annotationName);
                        rowVector = dataset.getRowMetadata().add(
                            annotationName);
                    }
                    var existingColumnVector = null;
                    var columnVector = null;
                    if (isColumns) {
                        existingColumnVector = dataset.getColumnMetadata()
                            .getByName(annotationName);
                        columnVector = dataset.getColumnMetadata().add(
                            annotationName);
                    }

                    for (var p = 0, nselected = eventData.points.length; p < nselected; p++) {
                        var item = array[eventData.points[p].pointNumber];
                        if (isRows) {
                            if (_.isArray(item.row)) {
                                item.row.forEach(function (r) {
                                    rowVector.setValue(r, value);
                                });

                            } else {
                                rowVector.setValue(item.row, value);
                            }

                        }
                        if (isColumns) {
                            columnVector.setValue(item.column, value);
                        }
                    }
                    if (isRows) {
                        morpheus.VectorUtil
                            .maybeConvertStringToNumber(rowVector);
                        _this.project.trigger('trackChanged', {
                            vectors: [rowVector],
                            render: existingRowVector != null ? []
                                : [morpheus.VectorTrack.RENDER.TEXT],
                            columns: false
                        });
                    }
                    if (isColumns) {
                        morpheus.VectorUtil
                            .maybeConvertStringToNumber(columnVector);
                        _this.project.trigger('trackChanged', {
                            vectors: [columnVector],
                            render: existingColumnVector != null ? []
                                : [morpheus.VectorTrack.RENDER.TEXT],
                            columns: true
                        });
                    }
                }
            });

    },
    draw: function () {
        var _this = this;
        this.$chart.empty();
        var plotlyDefaults = morpheus.ChartTool.getPlotlyDefaults();
        var layout = plotlyDefaults.layout;
        var config = plotlyDefaults.config;
        var chartWidth = 400;
        var chartHeight = 400;
        var showPoints = this.formBuilder.getValue('show_points');

        var groupColumnsBy = this.formBuilder.getValue('group_columns_by');
        var axisLabel = this.formBuilder.getValue('axis_label');
        var colorBy = this.formBuilder.getValue('color');
        var sizeBy = this.formBuilder.getValue('size');
        var groupRowsBy = this.formBuilder.getValue('group_rows_by');

        var dataset = this.project.getSelectedDataset({
            emptyToAll: false
        });
        this.dataset = dataset;
        if (dataset.getRowCount() * dataset.getColumnCount() === 0 || dataset.getRowCount() != 2) {
            $('<h4>Please select 2 rows and any number of columns in the heat map.</h4>')
                .appendTo(this.$chart);
            return;
        }
        if ((dataset.getRowCount() * dataset.getColumnCount()) > 100000) {
            showPoints = false;
        }

        var project = this.project;

        var expressionSet = project.getFullDataset().getESSession();
        var columnIndices = dataset.columnIndices;
        var rowIndices = dataset.rowIndices;

        var req = ocpu.call("pcaPlot", {
            es : expressionSet,
            columns : columnIndices,
            c1 : rowIndices[0],
            c2 : rowIndices[1],
            colour : colorBy,
            size : sizeBy
        }, function (session) {
            var img = $('<img />', {src : session.getLoc() + 'graphics/1/png'});
            _this.$chart.append(img);
        });
        req.fail(function () {
            alert("failed to create pcaPlot");
        })
    }
};


