'use strict';

angular.module('angularTreeview', [])
    .controller('dropdownTreeGmsCtrl', ['$scope', '$log',
        function($scope, $log) {

            $scope.emptyList = [];

            $scope.filterData = [];

            $scope.searchResults = [];
            $scope.currSearchIndex = '';
            $scope.collapseList = [];
            $scope.dateSearch = {};

            var tempList = [];
            var parentId;

            $scope.toggleExpand = function(option) {
                if ($scope.searchResults.length > 0 && $scope.searchResults[$scope.currSearchIndex][1]) {
                    for (var h = 0; h < $scope.searchResults[$scope.currSearchIndex][1].length; h++) {
                        $scope.searchResults[$scope.currSearchIndex][1][h].expanded = option;
                    }
                }
            }
            $scope.goToSearchResult = function(option) {
                switch (option) {
                    case 'init':
                        if ($scope.searchResults.length > 0) {
                            $scope.currSearchIndex = 0;
                            $scope.setSelection($scope.searchResults[$scope.currSearchIndex][0]);
                        }
                        break;
                    case 'next':
                        $scope.toggleExpand(false);
                        $scope.currSearchIndex = ($scope.currSearchIndex >= 0 && $scope.currSearchIndex < $scope.searchResults.length - 1) ? $scope.currSearchIndex + 1 : 0;
                        $scope.setSelection($scope.searchResults[$scope.currSearchIndex][0]);
                        break;
                    case 'previous':
                        $scope.toggleExpand(false);
                        $scope.currSearchIndex = ($scope.currSearchIndex > 0) ? $scope.currSearchIndex - 1 : $scope.searchResults.length - 1;
                        $scope.setSelection($scope.searchResults[$scope.currSearchIndex][0]);
                        break;
                    default:
                        console.log('bad request');
                        break;
                }
                $scope.toggleExpand(true);
            }

            $scope.clearSearchResults = function() {
                for (var k = 0; k < $scope.searchResults.length; k++) {
                    $scope.searchResults[k][0].secondarySearchResult = false;
                    $scope.searchResults[k][0].primarySearchResult = false;
                }
                $scope.searchResults = [];
                $scope.currSearchIndex = '';
            };

            $scope.recursiveSearch = function(currNode, searchValue, callback) {
            	var matched = false;
            	for (var element in currNode){
            		if (element === "started" || element === "completed"){
            			for (var subelement in currNode[element]){
            				if (typeof(currNode[element][subelement]) === "string" || typeof(currNode[element][subelement]) === "number"){
                    			if (currNode[element][subelement].toString().toLowerCase().indexOf(searchValue) >= 0) {
                    				callback(currNode);
                                    matched = true;
                    				break;
                                }
                    		}
            			}
            		} else if (typeof(currNode[element]) === "string" || (typeof(currNode[element]) === "number")){
            			if (currNode[element].toString().toLowerCase().indexOf(searchValue) >= 0) {
                            console.log(currNode.label);
                            callback(currNode);
                            matched = true;
                        }
            		}
            		if (matched){
            			break;
            		}
            	}
                if (!currNode.expanded) {
                    $scope.collapseList.push(currNode);
                }
                for (var j = 0; j < currNode.items.length; j++) {
                    $scope.recursiveSearch(currNode.items[j], searchValue, callback);
                }
                if (!currNode.expanded) {
                    $scope.collapseList.pop();
                }

            }
            
            
            
            var startSearch = function(newValue, oldValue){
                if (newValue !== oldValue) {
                    console.log('searching start');

                    var searchValue = newValue.toLowerCase();

                    if (searchValue.length <= 0) {
                        $scope.clearSearchResults();
                    } else if (oldValue && oldValue.length !== 0 && newValue.indexOf(oldValue) === 0) {
                        var tempList = [];
                        var hasMatch;
                        for (var i = 0; i < $scope.searchResults.length; i++) {
                        	hasMatch = false;
                        	for (var element in $scope.searchResults[i][0]){
                        		if (element === "started" || element === "completed"){
                        			for (var subelement in $scope.searchResults[i][0][element]){
                        				if (typeof($scope.searchResults[i][0][element][subelement]) === "string" || typeof($scope.searchResults[i][0][element][subelement]) === "number"){
                                			if ($scope.searchResults[i][0][element][subelement].toString().toLowerCase().indexOf(searchValue) >= 0) {
                                                tempList.push($scope.searchResults[i]);
                                                hasMatch = true;
                                                break;
                                            }
                                		}
                        			}
                        		} else if (typeof($scope.searchResults[i][0][element]) === "string" || typeof($scope.searchResults[i][0][element]) === "number"){
                        			if ($scope.searchResults[i][0][element].toString().toLowerCase().indexOf(searchValue) >= 0) {
                                        tempList.push($scope.searchResults[i]);
                                        hasMatch = true;
                                        break;
                                    }
                        		}
                        		if (hasMatch){
                        			break;
                        		}
                        	}
                            if (!hasMatch) {
                                $scope.searchResults[i][0].secondarySearchResult = false;
                                $scope.searchResults[i][0].primarySearchResult = false;
                            }
                        }
                        $scope.searchResults = tempList;
                        $scope.goToSearchResult('init');
                    } else {
                        $scope.clearSearchResults();
                        for (var k = 0; k < $scope.model.length; k++) {
                            $scope.recursiveSearch($scope.model[k], searchValue, function(currNode) {
                                $scope.searchResults.push([currNode, $scope.collapseList.slice(0)]);
                                currNode.secondarySearchResult = true;
                            });
                        }
                        $scope.goToSearchResult('init');
                    }

                    console.log($scope.searchResults);
                    console.log('searching end');
                }
            }

            $scope.$watch('searchValue', startSearch);

            $scope.searchKeyPress = function($event) {
                if ($scope.searchResults.length) {
                    if ($event.which === 40) {
                        $scope.goToSearchResult('next');
                        $event.preventDefault();
                    } else if ($event.which === 38) {
                        $scope.goToSearchResult('previous');
                        $event.preventDefault();
                    }
                }
            };

            var isNodeChecked = function(nodeId) {
                if (!$scope.model || !$scope.model.values) {
                    return false;
                }
                for (var id in $scope.model.values) {
                    if (id === nodeId) {
                        return true;
                    }
                }
                return false;
            }.bind(this);

            var augmentNode = function(node, parentId) {
                node.isChecked = isNodeChecked(node.id);
                node.isMid = false;
                node.isShow = true;
                node.expanded = false;
                node.parentId = parentId;

                if (!node.items) {
                    node.items = [];
                }
            };

            //create nodeLists and augment nodes
            var tempProcessNode = function(node, parentId) {
                tempList.push({
                    name: node.name,
                    id: node.id,
                    parentId: parentId
                });
                augmentNode(node, parentId);

                var checkedCount = 0;
                var isMid = false;

                for (var i = 0; i < node.items.length; i++) {
                    parentId = node.id;
                    tempProcessNode(node.items[i], parentId);
                    if (node.items[i].isChecked && !node.items[i].isMid) {
                        checkedCount++;
                    }
                    if (node.items[i].isMid) {
                        isMid = true;
                    }
                }

                node.isMid = node.isMid || (isMid || checkedCount > 0) && (checkedCount !== node.items.length);
                node.isChecked = node.isMid || node.isChecked || ((node.items.length > 0) && (checkedCount === node.items.length));

                if (node.isChecked && !node.isMid) {
                    if (!arrayContains($scope.model.names, node.name)) {
                        $scope.model.names.push(node.name);
                    }
                }
            };

            var populateFilter = function(response) {
                if (response && response.items) {
                    $scope.filterData = response.items;

                    for (var j = 0; j < $scope.filterData.length; j++) {
                        parentId = 0;
                        tempProcessNode($scope.filterData[j], parentId);
                    }
                }
                $scope.nodeList = tempList;
                tempList = [];
            }.bind(this);

            var arrayContains = function(arr, itemToFind) {
                var found = false;

                angular.forEach(arr, function(item) {
                    if (item === itemToFind) {
                        found = true;
                    }
                });

                return found;
            };

            // load the data
            $scope.$watch('model', function() {
                var includeIds = null;
                if ($scope.model && $scope.model.values) {
                    includeIds = $scope.model.values;
                }
                populateFilter({
                    'items': $scope.model
                });
            });


        }
    ]);