angular.module("app").directive("settingsTable", function ($rootScope, $state, SQEvents, SQConstants, $timeout, UniqueIdGenerator, L) {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: '../app/directives/settingsTable/settingsTable.html',
        scope: {
            instance: '=',
            afterInit: '=',
            onChange: '=',
            type: '@',
            customId: '@'
        },
        link: function (scope, element, attrs) {
            var initializing = true;

            var settings = []; //last settings of property grids

            var grid;
            scope.gridId = scope.customId ? scope.customId : UniqueIdGenerator.generateId();

            scope.propGridInstance = {};
            var loadingPG = false;

            scope.propGridShowed = false;

            scope.onPGChange = function (data) {
                if (loadingPG) {
                    return;
                }

                var rowIndex = grid.getSelectedRows().selectedRows[0];
                if (!valueFilled(rowIndex)) {
                    return;
                }

                //print formated name
                printFormatedName(data, rowIndex);

                //save last settings
                var rowId = grid.getRowId(rowIndex);
                settings[rowId] = data;

                onChange();
            }

            function printFormatedName(data, rowIndex) {
                var display = grid.getUserData(rowIndex, "display");
                var config = grid.getUserData(rowIndex, "config");

                for (var i = 0; i < data.length; i++) {
                    var property = data[i];
                    var value = property.value;
                    var key = property.key;

                    value = scope.propGridInstance.printValueByConfig(config, key, value);

                    display = L.tsq(display).replace("#" + key + "#", value);
                }
                grid.modifyRowByIndex(display, rowIndex, 2);
            }

            function afterInit() {
                grid = new sqGrid("grid-" + scope.gridId);

                var columns = [
                    { title: 'ID', type: "text", sort: 'text' },
                    { title: 'Use', type: "text", sort: 'text' },
                    { title: 'Name', type: "text", sort: 'text', align: 'left' }
                ];

                var widths = [1, 30, '*'];

                grid.setFirstColumnAsId(true, true);
                grid.setColumns(columns, !!grid);
                grid.setWidths(widths, !!grid);
                grid.setEmptyGridText('No settings defined.');
                grid.disableSorting();
                grid.enableCheckboxes(false);

                grid.defineWidget('checkboxWidget', sqGridCheckbox);

                grid.onSelectionChanged = function () {
                    onRowSelect(grid.getSelectedRowOnly());
                };

                grid.cellEventHandler = function (rowIndex, cellIndex, eventName, args) {
                    switch (eventName) {
                        case "checkboxChecked": onChange(); break;
                    }
                };

                grid.headerRedraw();

                if (scope.afterInit) {
                    scope.afterInit();
                }
            }

            scope.instance.load = function (data) {
                settings = [];
                initializing = true;

                grid.removeAllRows(true, true);

                for (var i = 0; i < data.rows.length; i++) {
                    var row = data.rows[i];

                    grid.addRow([row.id, "{{checkboxWidget}}", L.tsq(row.data[1])], true);
                    sqGridCheckboxSetValue(grid, i, 1, row.data[0], true);
                    grid.setUserData(i, "config", row.userdata.config);
                    grid.setUserData(i, "display", L.tsq(row.userdata.display));
                }

                grid.bodyRedraw();

                initializing = false;
            }

            scope.instance.getValuesXml = function (xmlDoc, methodsObj) {
                removeAllChildren(methodsObj);

                for (var i = 0; i < grid.getNumberOfRows(); i++) { //loop methods
                    var use = sqGridCheckboxGetValue(grid, i, 1);
                    var methodElem = xmlDoc.createElement('Method');
                    var methodObj = methodsObj.appendChild(methodElem);

                    var rowId = grid.getRowId(i);
                    methodObj.setAttribute("use", use);
                    methodObj.setAttribute("type", rowId);

                    var config = grid.getUserData(i, "config");

                    var values = rowId in settings ? settings[rowId] : [];
                    scope.propGridInstance.getValuesXmlByConfig(config, values, xmlDoc, methodObj);
                }
            }

            function onRowSelect(selectedRow) {
                if (selectedRow !== false) {
                    scope.propGridShowed = true;
                    var config = grid.getUserData(selectedRow.index, "config");
                    var rowId = grid.getRowId(selectedRow.index);

                    loadingPG = true;

                    //print properties  
                    scope.propGridInstance.createFromXML(config, function () {
                        //set last settings
                        if (rowId in settings) {
                            scope.propGridInstance.setValues(settings[rowId]);
                        }
                        loadingPG = false;
                    });
                }
                else {
                    scope.propGridInstance.clearAll();
                    scope.propGridShowed = false;
                }
                try {
                    scope.$digest();
                } catch (err) { }

            }

            scope.instance.applySettings = function (methods, callback) {
                if (!methods) {
                    return;
                }

                initializing = true;

                for (var i = 0; i < methods.length; i++) {
                    var method = methods[i];

                    settings[method.method] = method.params;

                    var rowIndex = grid.getRowIndex(method.method);
                    if (rowIndex >= 0) {
                        printFormatedName(method.params, rowIndex);
                        sqGridCheckboxSetValue(grid, rowIndex, 1, method.use, true);
                    }
                }

                if (grid.getNumberOfRows() > 0) {
                    grid.selectRow(0, true);
                    onRowSelect({ index: 0 });
                }

                grid.bodyRedraw();

                initializing = false;

                if (callback) {
                    callback();
                }
            }

            var enabled = true;
            scope.instance.setEnabled = function (isEnabled) {
                enabled = isEnabled;

                for (var i = 0; i < grid.getNumberOfRows(); i++) {
                    grid.setRowDisabled(i, !enabled);
                    grid.setRowClass(i, enabled ? "enabled" : "disabled");
                }

                scope.propGridInstance.setEnabled(enabled);
            }

            function onChange() {
                if (scope.onChange && !initializing) {
                    scope.onChange();
                }
            }

            $timeout(function () {
                afterInit();          //calls init in the next digest cycle, so the DOM will be ready
            }, 0, false);

            scope.$on("$destroy", function () {
                UniqueIdGenerator.removeId(scope.gridId);
            });
        }
    };
});