var app = angular.module('kbUser', ['ngSanitize', 'kb.search', 'kb.result', 'kb.wrapTextWithSpan', 'kb.setFocus', 'kb.blogPosts', 'kb.dropdown', 'kb.phoneList', 'kb.tooltip', 'kb.localization', 'kb.languageList']);

app.controller('ArticleCtrl', function ($scope, $location, $anchorScroll, $http) {
    $scope.scrollTo = function (id) {
        $location.hash(id);
        console.log($location.hash());
        $anchorScroll();
    };

    $scope.feedback = '';
    $scope.showRateButtons = true;
    $scope.showFeedback = false;
    $scope.showThank = false;
    $scope.rate = function (articleId, score) {
        if ($scope.showRateButtons) {
            $scope.showRateButtons = false;
            $scope.showFeedback = false;
            $scope.showThank = true;
            $http({
                url: 'backend/api/feedback/' + articleId,
                method: "PUT",
                data: {
                    "score" : score,
                    "comment" : $scope.feedback
                }
            });
        }
    };

    $http.get('backend/api/product').success(function (data) {
        $scope.products = data;
    });
});

app.filter('escape', function () {
    return window.encodeURIComponent;
});
angular.module('kb.blogPosts', ['xml', 'kb.localization'])
    .directive('kbBlogPosts', ['$http', 'xmlParser', function ($http, xmlFilter) {
        return {
            restrict: 'E',
            templateUrl: '/knowledge-base/scripts/components/blog-posts/blog-posts.html',
            replace: true,
            scope: {},
            link: function (scope, element) {
                scope.blogItems = [];

                $http.get('http://www.corsproxy.com/blog.intermedia.net/feed/').success(function (data) {
                    var xml = xmlFilter.parse(data);
                    var blogItems = angular.element(xml).find('item');
                    blogItems = blogItems.splice(0,3);

                    angular.forEach(blogItems, function (blogItem) {
                        scope.blogItems.push({
                            title: angular.element(blogItem).find('title').text(),
                            link: angular.element(blogItem).find('link').text(),
                            date: new Date(angular.element(blogItem).find('pubDate').text())
                        })
                    });
                });
            }
        };
    }
    ]);
angular.module('kb.search', ['kb.wrapTextWithSpan'])
    .factory('coveoService', ["$http",
        function ($http) {
            var coveoInfo = null;
            return {
                getCoveoInfo: function (culture, callBack) {
                    if (coveoInfo) {
                        callBack(coveoInfo);
                        return;
                    }

                    return $http.post('Coveo/GetInfo/', { culture: culture }).success(function (data) {
                        coveoInfo = data;
                        callBack(coveoInfo);
                    }).error(function (error) {
                        console.log("Get search url exception: " + error);
                    });
                }
            };
        }])
    .directive('kbSearch', ['$document', '$http', '$location', '$window', function ($document, $http, $location, $window) {
        return {
            restrict: 'E',
            scope: {
                autofocus: '@?',
                placeholder: '@?',
                value: '@?',
                culture: '@?'
            },
            templateUrl: 'scripts/components/search/search.html?v2',
            replace: true,
            controller: ['$scope', '$element', 'coveoService', function (scope, element, coveoService) {

                var searchUrl = '';
                var coveoSearchPage = '';

                coveoService.getCoveoInfo(scope.culture, function (response) {
                    searchUrl = response.url;
                    coveoSearchPage = response.coveoSearchPage;
                    if (scope.query) {
                        doSearch(scope.query);
                    }
                });

                // Set default value
                if (angular.isDefined(scope.value) && scope.value.length > 0) {
                    scope.query = scope.value;
                    scope.showResults = false;
                } else { // todo is it still used?
                    var regex = new RegExp("[\\?&]query=([^&#]*)"),
                        results = regex.exec($location.absUrl());
                    if (results) {
                        scope.query = decodeURIComponent(results[1].replace(/\+/g, " "));
                        scope.showResults = false;
                    }
                }

                // Set focus
                if (angular.isDefined(scope.autofocus) && scope.autofocus != 'off') {
                    scope.inputFocused = true;
                    scope.showResults = true;
                }

                // Hide results on click outside the search
                $document.bind('click', function (event) {
                    scope.$apply(function () {
                        scope.showResults = false;
                    });
                });

                element.bind('click', function (event) {
                    scope.$apply(function () {
                        scope.showResults = true;
                        event.stopPropagation();
                    });
                });

                var cacheResults = new Array();

                scope.searchResults = function () {
                    return cacheResults[scope.query];
                };

                scope.$watch('query', function (query) {
                    doSearch(query);
                });

                function doSearch(query) {
                    if (!searchUrl) {
                        return;
                    }

                    if (query) {
                        if (!cacheResults[query]) {
                            $http.get(searchUrl + '&q=' + window.encodeURIComponent(query)).success(function (data) {

                                for (var i = 0; i < data.results.length; i++) {
                                    resolveHighlights(data.results[i]);
                                    addKbQueryParam(data.results[i]);
                                }

                                cacheResults[query] = data;

                            }).error(function (error) {
                                console.log("Get coveo results exception: " + error);
                            });
                        }
                    }
                }

                function resolveHighlights(item) {
                    if (!item.titleHighlights || item.titleHighlights.length === 0) {
                        return;
                    }

                    var highlights = item.titleHighlights;
                    var resultTitle = item.title.substr(0, item.titleHighlights[0].offset);

                    var j = 0;
                    for (j; j < highlights.length; j++) {
                        // highlight word
                        resultTitle += "<span class=\"search-results-highlight\">" +
                            item.title.substr(highlights[j].offset, highlights[j].length) +
                            "</span>";
                        // add not highlighted text between highlighted
                        if (j + 1 < highlights.length) {
                            var endOfItemHighlight = highlights[j].offset + highlights[j].length;
                            resultTitle += item.title.substr(
                                endOfItemHighlight,
                                highlights[j + 1].offset - endOfItemHighlight);
                        }
                    }

                    var endOfHighlights = highlights[j - 1].offset + highlights[j - 1].length;
                    resultTitle += item.title.substr(endOfHighlights, item.title.length - endOfHighlights);

                    item.title = resultTitle;
                }

                function addKbQueryParam(item) {

                    if (!/\/article\/\d*$/gi.test(item.clickUri)) {
                        return;
                    }

                    item.clickUri = item.clickUri + (scope.query ? "?query=" + window.encodeURIComponent(scope.query) : "");
                }

                scope.submit = function () {
                    $window.location.href =
                        (scope.culture ? "/" + scope.culture : "")  + coveoSearchPage + (scope.query ? "#q=" + window.encodeURIComponent(scope.query) : "");
                };
            }]
        };
    }]);

angular.module('kb.result', ['kb.wrapTextWithSpan', 'kb.localization'])
    .filter('split', [function () {
            return function (input, token) {
                return input.split(token);
            };
        }])
    .directive('kbResult', ['$document', '$http', '$location', function ($document, $http, $location) {
        return {
            restrict: 'E',
            scope: {
                autofocus: '@?',
                placeholder: '@?',
                value: '@?',
                notfound: '@?'
            },
            templateUrl: 'scripts/components/search/result.html',
            replace: true,
            link: function (scope, element, attrs) {

                // Set default value
                if (angular.isDefined(scope.value) && scope.value.length > 0) {
                    scope.query = scope.value;
                    scope.showResults = false;
                } else {
                    var regexQuery = new RegExp("[\\?&]query=([^&#]*)"),
                        resultsQuery = regexQuery.exec($location.absUrl());
                    var regexPage = new RegExp("[\\?&]page=([^&#]*)"),
                        resultsPage = regexPage.exec($location.absUrl());
                    if (resultsQuery) {
                        scope.query = decodeURIComponent(resultsQuery[1].replace(/\+/g, " "));
                        scope.showResults = false;
                    }
                    
                    if (resultsPage) {
                        scope.page = decodeURIComponent(resultsPage[1].replace(/\+/g, " "));
                    } else {
                        scope.page = "0";
                    }
                }

                // Set focus
                if (angular.isDefined(scope.autofocus) && scope.autofocus != 'off') {
                    scope.inputFocused = true;
                    scope.showResults = true;
                }

                // Hide results on click outside the search
                $document.bind('click', function (event) {
                    scope.$apply(function () {
                        scope.showResults = false;
                    });
                });

                element.bind('click', function (event) {
                    scope.$apply(function () {
                        scope.showResults = true;
                        event.stopPropagation();
                    });
                });

                // Watch input model to update search result
                var cacheResults = new Array();
                var lastQuery;
                scope.$watch('query', function (query) {
                    lastQuery = query;
                    if (query) {
                        var result = cacheResults[query];
                        if (cacheResults.indexOf(query) >= 0 && result) {
                            if (lastQuery == query) {
                                scope.searchResults = result;
                            }
                        } else {
                            $http.get('backend/api/search?detail=1&page=' + scope.page + '&query=' + window.encodeURIComponent(query)).success(function (data) {
                                cacheResults[query] = data;
                                if (lastQuery == query) {
                                    scope.searchResults = data;
                                }
                            });
                        }
                    } else if (scope.notfound === '1' && typeof scope.query === 'undefined') {
                        scope.searchResults = { items: [] };
                    } else {
                        scope.searchResults = null;
                    }
                });
            }
        };
    }]);

angular.module('kb.setFocus', [])
    .directive('setFocus', ['$timeout', '$parse', function ($timeout, $parse) {
        return {
            //scope: true,   // optionally create a child scope
            link: function(scope, element, attrs) {
                var model = $parse(attrs.setFocus);
                scope.$watch(model, function(value) {
                    if(value === true) {
                        $timeout(function() {
                            element[0].focus();
                        });
                    }
                });
                // to address @blesh's comment, set attribute value to 'false'
                // on blur event:
                element.bind('blur', function() {
                    scope.$apply(model.assign(scope, false));
                });
            }
        };
    }]);
 angular.module('kb.wrapTextWithSpan', ['ngSanitize'])
    .filter('wrapTextWithSpan', [function () {
        return function (input, text, className) {
            var output = input;

            if (output.length > 0) {
                var find = new RegExp('(' + text + ')', 'ig');
                output = output.replace(find, '<span class="' + className + '">$1</span>');
            }

            return output;
        };
    }]);
angular.module('kb.dropdown', [])
    .constant('dropdownConfig', {
        openClass: 'm-open'
    })
    .service('dropdownService', ['$document', function ($document) {
        var openScope = null;

        this.open = function (dropdownScope) {
            if (!openScope) {
                $document.bind('click', closeDropdown);
                $document.bind('keydown', escapeKeyBind);
            }

            if (openScope && openScope !== dropdownScope) {
                openScope.isOpen = false;
            }

            openScope = dropdownScope;
        };

        this.close = function (dropdownScope) {
            if (openScope === dropdownScope) {
                openScope = null;
                $document.unbind('click', closeDropdown);
                $document.unbind('keydown', escapeKeyBind);
            }
        };

        var closeDropdown = function (evt) {
            // This method may still be called during the same mouse event that
            // unbound this event handler. So check openScope before proceeding.
            if (!openScope) {
                return;
            }

            var toggleElement = openScope.getToggleElement();
            if (evt && toggleElement && toggleElement[0].contains(evt.target)) {
                return;
            }

            openScope.$apply(function () {
                openScope.isOpen = false;
            });
        };

        var escapeKeyBind = function (evt) {
            if (evt.which === 27) {
                openScope.focusToggleElement();
                closeDropdown();
            }
        };
    }])
    .controller('DropdownController', ['$scope', '$attrs', '$parse', 'dropdownConfig', 'dropdownService', '$animate', function ($scope, $attrs, $parse, dropdownConfig, dropdownService, $animate) {
        var self = this,
            scope = $scope.$new(), // create a child scope so we are not polluting original one
            openClass = dropdownConfig.openClass,
            getIsOpen,
            setIsOpen = angular.noop,
            toggleInvoker = $attrs.onToggle ? $parse($attrs.onToggle) : angular.noop;

        this.init = function (element) {
            self.$element = element;

            if ($attrs.isOpen) {
                getIsOpen = $parse($attrs.isOpen);
                setIsOpen = getIsOpen.assign;

                $scope.$watch(getIsOpen, function (value) {
                    scope.isOpen = !!value;
                });
            }
        };

        this.toggle = function (open) {
            return scope.isOpen = arguments.length ? !!open : !scope.isOpen;
        };

        // Allow other directives to watch status
        this.isOpen = function () {
            return scope.isOpen;
        };

        scope.getToggleElement = function () {
            return self.toggleElement;
        };

        scope.focusToggleElement = function () {
            if (self.toggleElement) {
                self.toggleElement[0].focus();
            }
        };

        scope.$watch('isOpen', function (isOpen, wasOpen) {
            $animate[isOpen ? 'addClass' : 'removeClass'](self.$element, openClass);

            if (isOpen) {
                scope.focusToggleElement();
                dropdownService.open(scope);
            } else {
                dropdownService.close(scope);
            }

            setIsOpen($scope, isOpen);
            if (angular.isDefined(isOpen) && isOpen !== wasOpen) {
                toggleInvoker($scope, { open: !!isOpen });
            }
        });

        $scope.$on('$locationChangeSuccess', function () {
            scope.isOpen = false;
        });

        $scope.$on('$destroy', function () {
            scope.$destroy();
        });
    }])

    .directive('dropdown', function () {
        return {
            controller: 'DropdownController',
            link: function (scope, element, attrs, dropdownCtrl) {
                dropdownCtrl.init(element);
            }
        };
    })

    .directive('dropdownToggle', function () {
        return {
            require: '?^dropdown',
            link: function (scope, element, attrs, dropdownCtrl) {
                if (!dropdownCtrl) {
                    return;
                }

                dropdownCtrl.toggleElement = element;

                var toggleDropdown = function (event) {
                    event.preventDefault();

                    if (!element.hasClass('disabled') && !attrs.disabled) {
                        scope.$apply(function () {
                            dropdownCtrl.toggle();
                        });
                    }
                };

                element.bind('click', toggleDropdown);

                // WAI-ARIA
                element.attr({ 'aria-haspopup': true, 'aria-expanded': false });
                scope.$watch(dropdownCtrl.isOpen, function (isOpen) {
                    element.attr('aria-expanded', !!isOpen);
                });

                scope.$on('$destroy', function () {
                    element.unbind('click', toggleDropdown);
                });
            }
        };
    });
angular.module('kb.phoneList', []).directive('kbPhoneList', [
    function () {
        return {
            restrict: 'E',
            templateUrl: 'scripts/components/phone-list/phone-list.html',
            replace: true,
            scope: {},
            controller: function ($scope, $attrs) {
                $scope.countries = [
                    {
                        name: 'USA',
                        flag: 'content/images/flags/us.png',
                        phone: ' +1-800-379-7729'
                    },
                    {
                        name: 'UK',
                        flag: 'content/images/flags/uk.png',
                        phone: '+44 (0)20 3384 2158'
                    },
                    {
                        name: 'AUS',
                        flag: 'content/images/flags/au.png',
                        phone: '+61 1800 281 209'
                    },
                    {
                        name: 'NZ',
                        flag: 'content/images/flags/nz.png',
                        phone: '+64 800 995 049'
                    }
                ];

                function getSelectedCountry() {
                    var selectedCountryIndex = localStorage.getItem('selectedCountryIndex') || 0;
                    return $scope.countries[selectedCountryIndex] || $scope.countries[0];
                }

                $scope.selectedCountry = getSelectedCountry();

                $scope.selectCountry = function (country) {
                    $scope.selectedCountry = country;
                    localStorage.setItem('selectedCountryIndex', $scope.countries.indexOf(country));
                };
            }
        };
    }
]);

angular.module('kb.tooltip',[])
    .directive('kbTooltip', [function () {
        return {
            restrict: 'A',
            scope: {
                delay: '@?',
                disable: '=?',
                maxWidth: '@?',
                offsetX: '@?',
                offsetY: '@?',
                position: '@?',
                show: '=?',
                trigger: '@?',
                kbTooltip: '@?',
                interactiveTolerance: '@?',
                hideIfEmpty: '@?'
            },
            link: function (scope, element, attr) {
                $(element).tooltipster({
                    content: scope.kbTooltip,
                    delay: scope.delay || 10,
                    functionAfter: function () {
                        if (angular.isDefined(scope.show)) {
                            scope.show = false;
                        }
                    },
                    interactive: true,
                    maxWidth: scope.maxWidth || 300,
                    offsetX: scope.offsetX || 0,
                    offsetY: scope.offsetY || 0,
                    position: scope.position || 'top',
                    trigger: scope.trigger || 'hover',
                    contentAsHTML: true,
                    updateAnimation: false,
                    interactiveTolerance: scope.interactiveTolerance || 350
                });

                if (scope.trigger === 'focus') {
                    $(element).tooltipster('option', 'trigger', 'custom');

                    $(element)
                        .focus(function () {
                            $(this).tooltipster('show');
                        })
                        .blur(function () {
                            $(this).tooltipster('hide');
                        });
                }

                scope.$watch('kbTooltip', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        $(element).tooltipster('content', newValue);
                    }

                    if (scope.hideIfEmpty === "true") {
                        setDisableState();
                    }
                });

                scope.$watch('disable', function (newValue) {
                    setDisableState();
                });

                scope.$watch('show', function (newValue) {
                    if (newValue) {
                        $(element).tooltipster('show');
                    } else {
                        $(element).tooltipster('hide');
                    }
                });

                var setDisableState = function() {
                    if (scope.disable || hideEmptyTooltip()) {
                        $(element).tooltipster('disable');
                    } else {
                        $(element).tooltipster('enable');
                    }
                }

                var hideEmptyTooltip = function() {
                    return scope.hideIfEmpty === "true" && (scope.kbTooltip === null || scope.kbTooltip === undefined || scope.kbTooltip === '');
                }
            }
        };
    }]);
angular.module('kb.languageList', []).directive('kbLanguageList', [
    function () {
        return {
            restrict: 'E',
            templateUrl: '/scripts/components/culture-selector/cultureSelect.html',
            replace: true,
            scope: {},
            controller: function ($scope, $window) {
                function selectCurrentCulture() {
                    for (var i = 0; i < $scope.languageArr.length; i++) {
                        if ($scope.languageArr[i].IsCurrentCulture) {
                            $scope.interfaceCulture = $scope.languageArr[i];
                        }
                    }
                }

                $scope.languageArr = $window.cultures;

                $scope.selectLanguage = function (language) {
                    var date = new Date();
                    date.setDate(date.getDate() + 365);

                    document.cookie = "kb-culture=" + language.Value + "; path=/;expires=" + date.toUTCString() + ";";
                    $window.location.href = language.Url;
                    $scope.isLangOpen = false;
                };

                selectCurrentCulture();
            }
        };
    }
]);

