'use strict';
/** 
 * @controller ClassificationLabelController
 * @property scope 
 * @property route
 * @property location
 * @property timeout
 * @property System
 * @property ClassificationService
 */
var ClassificationLabelController =  angular.module('classifications.controllers.classification', [
    'system'
])
    .controller('ClassificationLabelController', [
        '$scope',
        '$route',
        '$location',
        '$window',
        '$timeout',
        'System',
        'ClassificationService',
        'LabelService',
        'LabelFactory',
        function($scope, $route, $location, $window, $timeout, System, ClassificationService, LabelService, LabelFactory) {

            $scope.alias = $route.current.pathParams["alias"];
            $scope.classification = { };
            $scope.query = $location.$$search || { };
            $scope.newLabel = { Color: '#FFFFFF' };
            $scope.label = {};
            $scope.labels = [];
            $scope.treeObject = {};
            
            $(".tooltip").tooltip();
         
            /**
            * @method refresh
            * @description gets list of labels for calssification
            */
            $scope.refresh = function () {
                if ($scope.isSearch()) {
                    LabelService.query(angular.extend({ }, $scope.query, { classification: $scope.alias }))
                        .then(function(data) {
                            $scope.labels = [];
                            for (var i = 0; i < data.labels.length; i++) {
                                if (data.labels[i].Parent == null) {
                                    $scope.labels.push(data.labels[i]);
                                }
                            }
                            $scope.pager = System.Pager.create({ page: $scope.query.page, total: data.total });
                        });
                } else {
                    LabelService.top({ alias: $scope.alias }).then(function(data) {
                        $scope.labele = qusion.list.jsTree(data.labels, "ID", "Name");
                        $scope.labels = qusion.list.hierarchy(data.labels);

                        $timeout(function() {
                            $("#treeLabels").treetable({
                                expandable: true,
                                column: 1,
                                expanderTemplate: '<a href="#">&nbsp;</a>',
                                indenterTemplate: '<span class="indenter">&nbsp</span>',
                                onNodeCollapse: function () {
                                    LabelFactory.removeExpanded(this.id);
                            },
                            onNodeExpand: function (e) {
                                LabelFactory.addExpanded(this.id);
                            }
                        });
                           
                            var expanded = LabelFactory.allExpanded();
                        for (var i = 0; i < expanded.length; i++) {
                            $("#treeLabels").treetable("expandNode", expanded[i]);
                        }
                        }, 100);
                    });
                }
            };

            /**
            * @method get
            * @param Id
            * @description ClassificationService gets Classification data by its alias
            */
            $scope.refreshClassification = function () {
                ClassificationService.getByAlias($scope.alias)
                    .then(function(data) {
                        $scope.classification = data;
                    });
            };

            /**
            * @method search
            * @description searches labels inside classification 
            */
            $scope.search = function(q, reset) {
                reset ? $scope.query = q : angular.extend($scope.query, q);
                $location.search($scope.query);
                $scope.refresh();
            };

            /**
            * @method isSearch
            * @description returns value indicates if search is running
            */
            $scope.isSearch = function() {
                return Object.keys($scope.query).length !== 0;
            };

            /**
            * @method reset
            * @description resets search to its initial value
            */
            $scope.reset = function() {
                $location.search(($scope.query = { }));
                $scope.refresh();
            };

           /**
            * @method create
            * @description creates a new label
            */
            $scope.create = function() {
                $scope.newLabel.ClassificationID = $scope.classification.ID;
                LabelService.create($scope.newLabel)
                    .then(function (response) {
                        if (response.Errors) {
                            $scope.errors = response.Errors;
                            System.Message.error($scope.$resource('classifications.LabelCreatedError'));
                        } else {
                            $scope.newLabel = { ClassificationID: $scope.classification.ID };
                            $scope.refresh();
                            System.Message.success($scope.$resource('classifications.LabelCreated'));
                        }
                    });
            };
            
            /**
            * @method createChild
            * @description creates a new child label
            */
            $scope.createChild = function () {
                $scope.newLabel.ClassificationID = $scope.label.Classification.ID;
                $scope.newLabel.ParentID = $scope.label.ID;
                LabelService.create($scope.newLabel)
                    .then(function (label) {
                        if (label.Errors) {
                            $scope.errors = label.Errors;
                            System.Message.error($scope.$resource('classifications.LabelCreatedError'));
                        } else {
                            $scope.label.Children.push(label);
                            $scope.newLabel = { ClassificationID: $scope.label.Classification.ID };
                            $scope.refresh();
                            $scope.dialogCreate.dialog("close");
                            System.Message.success($scope.$resource('classifications.LabelCreated'));
                        }
                        
                    });
            };
            
            /**
            * @method update
            * @description updates existing label
            */
            $scope.update = function() {
                LabelService.update($scope.label)
                    .then(function(label) {
                        if (label.Errors) {
                            $scope.errors = label.Errors;
                            System.Message.error($scope.$resource('classifications.LabelCreatedError'));
                        } else {
                            $scope.label.Children.push(label);
                            $scope.refresh();
                            $scope.dialogEdit.dialog("close");
                            System.Message.success($scope.$resource('classifications.LabelUpdated'));
                        }
                    });
            };

            /**
            * @method remove
            * @description removes label by it's id
            */
            $scope.remove = function(label, index) {
                if ($window.confirm($scope.$resource('utility.areYouShure'))) {
                    LabelService.remove({ id: label.ID }).then(function (response) {
                        if (response.Errors) {
                            $scope.errors = response.Errors;
                            if (label.Children.length > 0)
                                System.Message.error($scope.$resource('classifications.child_label_first'));
                            else {
                                System.Message.error($scope.$resource('classifications.not_possible_delete'));
                            }
                        } else {
                            $scope.labels.splice(index, 1);
                                System.Message.success($scope.$resource('utility.deleted'));
                        }
                    });
                }
            };
            
            $scope.treeOptions = {
                dnd: {
                    onDragStart: function (node) {
                        /** This function MUST be defined to enable dragging for the tree.
                         *  Return false to cancel dragging of node.
                         */
                        logMsg("tree.onDragStart(%o)", node);
                        return true;
                    },
                    onDragStop: function (node) {
                        // This function is optional.

                        $scope.reordered = qusion.list.jsTreeOrdered($scope.treeObject.toDict().children);
                        $scope.$apply();

                    },
                    autoExpandMS: 1000,
                    preventVoidMoves: false, // Prevent dropping nodes 'before self', etc.
                    onDragEnter: function (node, sourceNode) {
                        /** sourceNode may be null for non-dynatree droppables.
                         *  Return false to disallow dropping on node. In this case
                         *  onDragOver and onDragLeave are not called.
                         *  Return 'over', 'before, or 'after' to force a hitMode.
                         *  Return ['before', 'after'] to restrict available hitModes.
                         *  Any other return value will calc the hitMode from the cursor position.
                         */
                        //logMsg("tree.onDragEnter(%o, %o)", node, sourceNode);
                        return true;
                    },
                    onDragOver: function (node, sourceNode, hitMode) {
                        /** Return false to disallow dropping this node.
                         *
                         */
                        //logMsg("tree.onDragOver(%o, %o, %o)", node, sourceNode, hitMode);
                        // Prevent dropping a parent below it's own child
                        if (node.isDescendantOf(sourceNode)) {
                            return false;
                        }
                        // Prohibit creating childs in non-folders (only sorting allowed)
                        if (!node.data.isFolder && hitMode === "over") {
                            return "after";
                        }
                    },
                    onDrop: function (node, sourceNode, hitMode, ui, draggable) {
                        /** This function MUST be defined to enable dropping of items on
                         * the tree.
                         */
                        // logMsg("tree.onDrop(%o, %o, %s)", node, sourceNode, hitMode);
                        sourceNode.move(node, hitMode);
                        // expand the drop target
                        //        sourceNode.expand(true);
                    },
                    onDragLeave: function (node, sourceNode) {
                        /** Always called if onDragEnter was called.
                         */
                        // logMsg("tree.onDragLeave(%o, %o)", node, sourceNode);
                    }

                }
            };

            /**
           * @action goToLabel
           * @description go to label view.
           */
            $scope.goToLabel = function (label) {
                if (label.ClassificationClassificationType == "Hierarchy")
                    $location.url('/label/' + label.ID);
            };

            $scope.editDialog = function(label) {
                $scope.label = label;
                $scope.dialogEdit.dialog("open");
            };

            $scope.dialogEdit = {};
            
            $scope.ui.dialogEdit = {
                width: 300,
                create: function () {
                    $scope.dialogEdit = $(this);
                }
            };
            
            /**
            *@method cancelUpdate Close dialog and clears dialog data.
            */
            $scope.cancelEdit = function () {
                $scope.refresh();
                $scope.dialogEdit.dialog("close");
            };
            
            $scope.createDialog = function (label) {
                $scope.label = label;
                $scope.dialogCreate.dialog("open");
            };

            $scope.dialogCreate = {};

            $scope.ui.dialogCreate = {
                width: 300,
                create: function () {
                    $scope.dialogCreate = $(this);
                }
            };

            /**
            *@method cancelCreate Close dialog and clears dialog data.
            */
            $scope.cancelCreate = function () {
                $scope.refresh();
                $scope.dialogCreate.dialog("close");
            };
            
            $scope.ui.reorderDialog = {
                width: 700,
                title: $scope.$resource('classifications.reorder_titlefac'),
                create: function () {
                    $scope.reorderDialog = $(this);
                }
            };

            $scope.openReordering = function () {
                $scope.reorderDialog.dialog("open");
            };

            /**
            *@method doneReordering Reorders labels by ordinal property.
            */
            $scope.doneReordering = function () {
                LabelService.reorder($scope.reordered).then(function (data) {
                    System.Message.success($scope.$resource('classifications.reordered'));
                    $scope.reorderDialog.dialog("close");
                  

                });
            };

            $scope.cancelReordering = function () {
                $scope.reorderDialog.dialog("close");
            };

            /**
           * @method back
           * @description redirects user to classifications list
           */
            $scope.back = function() {
                $location.path('/classifications');
            };

            $scope.refresh();
            $scope.refreshClassification();
        }
    ]);