/**
 * @author vpavlyuk
 *
 * Depends on JQuery 1.4.2 and sf-start.js
 */

(function() {

    var data,
        state = {},
        pageBrowser,
        ALL = 'all',
        RS = '_res',
        itemsPerPage,
        pbDefault,
        historyReady;


    /**
     * Init resource center
     */
    function init() {
        if(!(SF.ns('Resources.List')).ready) return;

        data = SF.Resources.List.data;
        historyReady = !!(SF.ns('History') && SF.History.ready);

        itemsPerPage = parseInt(data.itemsPerPage);

        pbDefault = {start: 1, count: itemsPerPage};


        //Itialize History
        if(historyReady) {
            SF.History.addCallback('res', historyCallback);
            setTimeout(function(){ SF.on('Resources:StateChanged', updateURLHash) }, 100);
        }

        //Attach event listeners
        $('#resource_media').change(function(e){
            SF.fire('Resources:TypeChanged', SF.extend({ type: $(this).val() }, pbDefault));
            $(this).blur();
        });

        $('#resource_tag').change(function(e){
            SF.fire('Resources:TagChanged', SF.extend({ tag: $(this).val() }, pbDefault));
            $(this).blur();
        });

        //Set up page browser
        pageBrowser = new SF.widget.PageBrowser('#res-pages', data.strings);
        pageBrowser.onChange(updateState);
        SF.on('PageBrowser:update', pageBrowser.update);
        SF.on('PageBrowser:updateSelctedPage', pageBrowser.setSelectedPage);

        SF.on('Resources:TypeChanged', updateState);
        //We need update tag selector when type changes
        SF.on('Resources:TypeChanged', updateTagSelector);

        SF.on('Resources:TagChanged', updateState);
        //We need update type selector when tag changes
        SF.on('Resources:TagChanged', updateTypeSelector);

        SF.on('Resources:StateChanged', updateList);

        SF.on('Resources:VisibilityUpdated', updateVisibility)

        SF.fire('Resources:StateChanged', pbDefault);


        // initial fire
        setTimeout(function(){SF.fire('Resources:TagChanged', SF.extend({ tag: $('#resource_tag').val()}, pbDefault)); }, 500);
        setTimeout(function(){SF.fire('Resources:TypeChanged', SF.extend({ type: $('#resource_media').val() }, pbDefault)); }, 500);
    }


    /**
     * Update state of filters if they are changed.
     * This method listens all events which are fired when filter(s) change(s).
     *
     * @param {Object} obj
     */
    function updateState(obj) {

        for(var key in obj) {
            if(obj[key] === ALL) {
                if(state.hasOwnProperty(key)) {
                    delete state[key];
                }
            } else {
                state[key] = obj[key];
            }
        }


        SF.fire('Resources:StateChanged', state);
    }


    /**
     * Updates the list of resources according to the current state of filters and page browser.
     *
     * @param {Object} state
     */
    function updateList(state) {
        var byTag,
            byType,
            itemsToShow = [],
            itemsCount,
            selector;

        //updateSelectors(state);

        //Make array of visible resources
        //Check for selected tag. If there is tag isn't present then all tags are selected.
        if(state.hasOwnProperty('tag')) {
            byTag = data.tags[state['tag']];
        }

        //Check for selected type. If there is type isn't present then all types are selected.
        if(state.hasOwnProperty('type')) {
            byType = data.types[state['type']];
        }

        //If both filters are set we need to find intersaction of arrays - logical AND
        //If one filter is set its list is used.
        //If nothing is set all items should be displayed.
        if(byTag && byType) {
            var small,
                big;

            if(byTag.length < byType.length) {
                small = byTag;
                big = byType;
            } else {
                small = byType;
                big = byTag;
            }

            for(var i = 0, len = small.length; i < len; i++) {
                if($.inArray(small[i], big) > -1) {
                    itemsToShow.push(small[i]);
                }
            }
        } else {
            itemsToShow = byTag || byType;
        }

        //Create array of visible items
        if (typeof itemsToShow == 'undefined') {
            itemsToShow = [];
             $.each(data.resourcesSorted, function(i, uid) {
                 itemsToShow.push(uid);
              });
            itemsCount = itemsToShow.length;
            itemsToShow = itemsToShow.slice(state.start - 1, state.start - 1 + state.count);
        } else if(itemsToShow.length == 0) {
            //Show No Items message
            SF.fire('Resources:NoItemsFound');
            itemsCount = 0;
        } else {
            itemsCount = itemsToShow.length;
            itemsToShow = itemsToShow.slice(state.start - 1, state.start - 1 + state.count);
        }

        SF.fire('PageBrowser:update', itemsCount, itemsPerPage, Math.floor((+state.start)/itemsPerPage) + 1);
        SF.fire('Resources:VisibilityUpdated', itemsToShow);
    }


    /**
     * Hides/Shows items according to given array of items
     *
     * @param {Array} itemsToShow
     */
    function updateVisibility(itemsToShow) {
        var selector = [];
        for(var i = 0, len = itemsToShow.length; i < len; i++) {
            selector.push('#' + itemsToShow[i] + RS);
        }
        $('.rl-progress').slideUp('fast');
        $('div.rl-item').not(selector.join(',')).addClass('hidden-h0');
        $(selector.join(',')).removeClass('hidden-h0').removeClass('even').filter(':odd').addClass('even');
    }


    /**
     * Update tag selector when type is changed
     *
     * @param {Object} obj
     */
    function updateTagSelector(obj) {
        var tags,
            selTag,
            select = document.getElementById('resource_tag'),
            o;

        if(!select){ return };

        o = select.options;

        //Remember currently selected Tag
        selTag = o[select.selectedIndex].value;

        if(obj.type && obj.type !== ALL) {
            tags = data.typesWithTags[obj['type']];

            o.length = 1;
            for(var i = 0, len = tags.length; i < len; i++) {
            	console.log(data.tagsDef[tags[i]]['tag_name']);
                o[o.length] = new Option(data.tagsDef[tags[i]]['tag_name'], tags[i], false, selTag === tags[i]);
            }

        } else {
			//Show all tags
			o.length = 1;
			var sortable = [];
			for(var key in data.tagsDef){
				sortable.push([key, data.tagsDef[key]['tag_name']]);
			}
			   
			sortable.sort(
				function(a, b) {
					var one = a[1];
					var two = b[1];
				return one.localeCompare(two);
				}
			);
			for(var item in sortable) {
				o[o.length] = new Option(sortable[item][1], sortable[item][0], false, selTag === key);
			}
        }
        // get the select
        //
    }


    /**
     * Update type selector when tag is changed
     *
     * @param {Object} obj
     */
    function updateTypeSelector(obj) {
        var types,
            selType,
            select = document.getElementById('resource_media'),
            o;

        if(!select) return;

        o = select.options;

        //Remember currentrly selected Tag
        selType = o[select.selectedIndex].value;

        var sortedTypes = new Array();
        var keysTypes = new Array();
        if(obj.tag && obj.tag !== ALL) {
            types = data.tagsWithTypes[obj['tag']];

            for(var i = 0, len = types.length; i < len; i++) {
            	// fill array with types
            	sortedTypes[i] = data.typesDef[types[i]]['type_name'];
            	// fill array type-key association
            	keysTypes[data.typesDef[types[i]]['type_name']] = types[i];
            }

            o.length = 1;
            sortedTypes.sort();
            for(var i = 0, len = sortedTypes.length; i < len; i++) {
            	// get current type id from array with type-key association
            	var typeId = keysTypes[sortedTypes[i]];
            	// set option
                o[o.length] = new Option(sortedTypes[i], typeId, false, selType === typeId);
            }

        } else {
            // show all tags
            for(var key in data.types) {
            	// fill array with types
            	sortedTypes[key] = data.typesDef[key]['type_name'];
            	// fill array with type-key association
            	keysTypes[data.typesDef[key]['type_name']] = key;
            }

            o.length = 1;
            // sort types
            sortedTypes.sort();
            for(var key in sortedTypes) {
            	// get current type id from array with type-key association
            	var typeId = keysTypes[sortedTypes[key]];
            	// set option
                o[o.length] = new Option(sortedTypes[key], typeId, false, selType === typeId);
            }
        }
    }


    /**
     * Is called when URL hash is changed.
     * Compose state object according to URL data and fire event.
     *
     * @param {Object} hashObj
     * @param {String} hashStr
     */
    function historyCallback(hashObj, hashStr){
        var selPage;

        state = { target: 'history' };

        if(hashObj.tag) {
            state.tag = hashObj.tag.split(',')[0];
            $('#resource_tag').val(state.tag);
            updateTypeSelector({tag: state.tag});
        } else {
            updateTypeSelector({tag: ALL});
            $('#resource_tag').val(ALL);
        }

        if(hashObj.type) {
            state.type = hashObj.type.split(',')[0];
            $('#resource_media').val(state.type);
            updateTagSelector({type: state.type});
        } else {
            updateTagSelector({type: ALL});
            $('#resource_media').val(ALL);
        }

        if(hashObj.count && hashObj.start) {
            state.count = +hashObj.count;
            state.start = +hashObj.start;

            selPage = Math.floor(state.start/itemsPerPage) + 1;
        } else {
            SF.extend(state, pbDefault);
            selPage = 1;
        }

        //Update page browser
        SF.fire('PageBrowser:updateSelctedPage', selPage);
        SF.fire('Resources:StateChanged', state);
    }


    /**
     * Call History.load()
     *
     * @param {Object} obj
     */
    function updateURLHash(obj) {
        var hObj = {};

        if(obj.target !== 'history') {
            if(data.tagsDef[obj.tag]) {
                hObj.tag = obj.tag + ',' + data.tagsDef[obj.tag]['tag_name']
            }

            if(data.typesDef[obj.type]) {
                hObj.type = obj.type + ',' + data.typesDef[obj.type]['type_name'];
            }

            if(obj.start) {
                hObj.start =  obj.start;
            }

            if(obj.count) {
                hObj.count =  obj.count;
            }

            SF.History.load({res: hObj});
        } else {
            delete state.target;
        }

    }

    SF.RequestForm.addToLinks('.res-list a', function(target){
    //console.log("...");
        var container,
            resourceId,
            result = {},
            path;

        container = $(this).parents('.rl-item');
        path = $(this).attr('href');

        if(container.length) {
            resourceId = parseInt(container.attr('id'));
            result = {
                "[tx_sfresource_pi1.][resourceId]": resourceId,
                "[tx_sfresource_pi1.][offer_name]": document.location.protocol + '//' + document.location.host + '/' + path
            };
        }

        return result;
    });
    SF.addToDOMReady(init);

})();
