// (C) Copyright 2011-2012 Hewlett-Packard Development Company, L.P.
/**
 * @type {VisualizerPresenter}
 */
define(['hp/services/IndexService',
    'hp/core/Router',
    'hp/core/UrlFragment',
    'hp/core/LinkTargetBuilder',
    'hp/services/IndexFilter',
    'hp/core/EventDispatcher'], 
function(indexService, router, urlFragment, linkTargetBuilder, IndexFilter, EventDispatcher) {"use strict";

    var VisualizerPresenter = ( function() {
      
        var INDEX_COUNT = 1000;
        var OMIT_CATEGORIES = ['alert', 'task'];

        /**
         * @constructor
         */
        function VisualizerPresenter() {
          
            var dispatcher = new EventDispatcher();
            var categories = [];
            var pendingCategories = 0;
            var pendingFilter = null;
            
            function getRelations(uri) {
                if (uri) {
                    indexService.getParentAndChildrenAssociations({
                        uri: uri,
                        handlers: {
                            success: function (tree) {
                                dispatcher.fire("treeChange", tree);
                            }
                        }
                    });
                }
            }
            
            var getCategoryResults; // for Sonar
            
            function getFilterResults(filter) {
                if (filter && filter.getUserQuery()) {
                    indexService.searchIndexResources(filter,
                        0, INDEX_COUNT,
                        {success: function (indexResults) {
                            indexResults.filter = filter;
                            dispatcher.fire('filterIndexResultsChange', indexResults);
                        }});
                } else {
                    getCategoryResults();
                }
            }
            
            function getCategory(category) {
                indexService.getFilteredIndexResources(
                    {data: {category: category, start: 0, count: INDEX_COUNT}},
                    {success: function (indexResults) {
                        indexResults.category = category;
                        dispatcher.fire('categoryIndexResultsChange', indexResults);
                        pendingCategories -= 1;
                        if (0 === pendingCategories && pendingFilter) {
                            getFilterResults(pendingFilter);
                            pendingFilter = null;
                        }
                }});
            }
            
            getCategoryResults = function() {
                dispatcher.fire('categoryIndexResultsReset');
                $.each(categories, function (index, category) {
                    getCategory(category);
                });
            };
            
            function getCategories() {
                var allCategories = linkTargetBuilder.categories();
                categories = $.grep(allCategories, function (category) {
                    if ($.inArray(category, OMIT_CATEGORIES) !== -1) {
                        return false;
                    } else {
                        return true;
                    }
                });
                    
                pendingCategories = categories.length;
                dispatcher.fire('categoriesChange', categories);
                getCategoryResults();
            }
            
            function onRouteChange(location) {
                var filter = new IndexFilter(location);
                if (categories.length === 0) {
                    pendingFilter = filter;
                    getCategories();
                } else {
                    getFilterResults(filter);
                }
            }
            
            /**
             * @public
             */
            this.init = function() {
                router.watch('visualizer route change',
                    '/visualizer?.*', {change: onRouteChange});
            };
            
            this.pause = function () {
            };
            
            this.resume = function () {
                //getCategories();
            };
            
            this.setSelectedItemUri = function (uri) {
                getRelations(uri);
            };
            
            this.setFilterStatus = function (status) {
                var filter = new IndexFilter(router.location());
                if (status && 'all' !== status) {
                    filter.setProperty('status', status);
                    router.go(filter.updateLocation(router.location()),
                        "status filter change");
                } else {
                    filter.unsetProperty('status');
                    router.go(filter.updateLocation(router.location()),
                        "status filter change");
                }
            };
            
            /**
             * Add a listener for a specified event.
             * @public
             * @param {string} eventName The name of the event.
             * @param {function(...)}
             */
            this.on = function(eventName, callback) {
                dispatcher.on(eventName, callback);
            };
            
            this.off = function(eventName, callback) {
                dispatcher.off(eventName, callback);
            };
        }

        return new VisualizerPresenter();
    }());

    return VisualizerPresenter;
});
