/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

(function() {
	'use strict';

	var eagleComponents = angular.module('eagle.components');

	eagleComponents.directive('sortTable', function($compile) {
		return {
			restrict: 'AE',
			scope: true,
			//terminal: true,
			priority: 1001,

			/**
			 * @param $scope
			 * @param $element
			 * @param {{}} $attrs
			 * @param {string} $attrs.sortTable			Data source
			 * @param {string?} $attrs.isSorting		Will bind parent variable of sort state
			 * @param {string?} $attrs.scope			Will bind parent variable of current scope
			 * @param {string?} $attrs.sortpath			Default sort path
			 * @param {[]?} $attrs.searchPathList		Filter search path list
			 * @param {string?} $attrs.maxSize			Set max display size of page
			 */
			controller: function($scope, $element, $attrs) {
				var sortmatch;
				var worker;
				var worker_id = 0;
				if(typeof(Worker) !== "undefined") {
					worker = new Worker("public/js/worker/sortTableWorker.js?_=" + window._TRS());
				}

				// Initialization
				$scope.pageNumber = 1;
				$scope.pageSize = 10;
				$scope.maxSize = $attrs.maxSize || 10;
				$scope.search = "";
				$scope.orderKey = "";
				$scope.orderAsc = true;

				if($attrs.sortpath) {
					sortmatch = $attrs.sortpath.match(/^(-)?(.*)$/);
					if(sortmatch[1]) {
						$scope.orderAsc = false;
					}
					$scope.orderKey = sortmatch[2];
				}

				// UI - Column sort
				$scope.doSort = function(path) {
					if($scope.orderKey === path) {
						$scope.orderAsc = !$scope.orderAsc;
					} else {
						$scope.orderKey = path;
						$scope.orderAsc = true;
					}
				};
				$scope.checkSortClass = function(key) {
					if($scope.orderKey === key) {
						return "fa sort-mark " + ($scope.orderAsc ? "fa-sort-asc" : "fa-sort-desc");
					}
					return "fa fa-sort sort-mark";
				};

				// List filter & sort
				function setState(bool) {
					if(!$attrs.isSorting) return;

					$scope.$parent[$attrs.isSorting] = bool;
				}


				var cacheSearch = "";
				var cacheOrder = "";
				var cacheOrderAsc = null;
				var cacheFilteredList = null;
				$scope.getFilteredList = function () {
					if(
						cacheSearch !== $scope.search ||
						cacheOrder !== $scope.orderKey ||
						cacheOrderAsc !== $scope.orderAsc ||
						!cacheFilteredList
					) {
						cacheSearch = $scope.search;
						cacheOrder = $scope.orderKey;
						cacheOrderAsc = $scope.orderAsc;

						var fullList = $scope.$parent[$attrs.sortTable] || [];
						if(!cacheFilteredList) cacheFilteredList = fullList;

						if(!worker) {
							cacheFilteredList = __sortTable_generateFilteredList(fullList, cacheSearch, cacheOrder, cacheOrderAsc, $scope.$parent[$attrs.searchPathList]);
							setState(false);
						} else {
							worker_id += 1;
							setState(true);
							var list = JSON.stringify(fullList);
							worker.postMessage({
								search: cacheSearch,
								order: cacheOrder,
								orderAsc: cacheOrderAsc,
								searchPathList: $scope.$parent[$attrs.searchPathList],
								list: list,
								id: worker_id
							});
						}
					}

					return cacheFilteredList;
				};

				// Week watch. Will not track each element
				$scope.$watch($attrs.sortTable + ".length", function () {
					cacheFilteredList = null;
				});
				$scope.$watch($attrs.sortTable + ".___SORT_TABLE___", function () {
					var fullList = $scope.$parent[$attrs.sortTable];
					if(fullList && !fullList.___SORT_TABLE___) {
						fullList.___SORT_TABLE___ = +new Date();
						cacheFilteredList = null;
					}
				});

				function workMessage(event) {
					var data = event.data;
					if(worker_id !== data.id) return;

					setState(false);
					cacheFilteredList = data.list;
					$scope.$apply();
				}
				worker.addEventListener("message", workMessage);

				$scope.$on('$destroy', function() {
					worker.removeEventListener("message", workMessage);
				});

				// Scope bind
				if($attrs.scope) {
					$scope.$parent[$attrs.scope] = $scope;
				}
			},
			compile: function ($element) {
				var contents = $element.contents().remove();

				return {
					post: function preLink($scope, $element) {
						$scope.defaultPageSizeList = [10, 25, 50, 100];

						$element.append(contents);

						// Tool Container
						var $toolContainer = $(
							'<div class="tool-container clearfix">' +
							'</div>'
						).insertBefore($element.find("table"));

						// Search Box
						var $search = $(
							'<div class="search-box">' +
							'<input type="search" class="form-control input-sm" placeholder="Search" ng-model="search" />' +
							'<span class="fa fa-search" />' +
							'</div>'
						).appendTo($toolContainer);
						$compile($search)($scope);

						// Page Size
						var $pageSize = $(
							'<div class="page-size">' +
							'Show' +
							'<select class="form-control" ng-model="pageSize" convert-to-number>' +
							'<option ng-repeat="size in pageSizeList || defaultPageSizeList track by $index">{{size}}</option>' +
							'</select>' +
							'Entities' +
							'</div>'
						).appendTo($toolContainer);
						$compile($pageSize)($scope);

						// Non-Sort Column
						$element.find("table thead th:not([sortpath])").each(function () {
							var $this = $(this);
							$compile($this)($scope);
						});

						// Sort Column
						$element.find("table [sortpath]").each(function () {
							var $this = $(this);
							var _sortpath = $this.attr("sortpath");
							$this.attr("ng-click", "doSort('" + _sortpath + "')");
							$this.prepend('<span ng-class="checkSortClass(\'' + _sortpath + '\')"></span>');
							$compile($this)($scope);
						});

						// Repeat Items
						var $tr = $element.find("table [ts-repeat], table > tbody > tr").filter(":first");
						$tr.attr("ng-repeat", 'item in getFilteredList().slice((pageNumber - 1) * pageSize, pageNumber * pageSize) track by $index');
						$compile($tr)($scope);

						// Page Navigation
						var $navigation = $(
							'<div class="navigation-bar clearfix">' +
							'<span>' +
							'show {{(pageNumber - 1) * pageSize + 1}} to {{pageNumber * pageSize}} of {{getFilteredList().length}} items' +
							'</span>' +
							'<uib-pagination total-items="getFilteredList().length" ng-model="pageNumber" boundary-links="true" items-per-page="pageSize" max-size="maxSize"></uib-pagination>' +
							'</div>'
						).appendTo($element);
						$compile($navigation)($scope);
					}
				};
			}
		};
	});

	eagleComponents.directive('convertToNumber', function() {
		return {
			require: 'ngModel',
			link: function(scope, element, attrs, ngModel) {
				ngModel.$parsers.push(function(val) {
					return parseInt(val, 10);
				});
				ngModel.$formatters.push(function(val) {
					return '' + val;
				});
			}
		};
	});
})();
