﻿// ajax callback / page load logic
CategorisedProductListing_OnLoad = function(sender, args) {
    var hasErrors = checkForException();

    $('[jQHHIPP]').bind('change', function(event) {
        customHistoryManager.onClick(event);
        return false;
    });

    try {
        var top = ($('ul.elementProductMain .title').height() - $('ul.elementProductMain .title a').height()) / 2;
        $('ul.elementProductMain .title a').css('margin-top', top);
    } catch (e) {

    }
};

CategorisedProductListing_OnResponseEnd = function(sender, args) {
    CategorisedProductListing_Initialise();

    setTimeout(function() {
        trace('CategorisedProductListing_OnResponseEnd');
        CategorisedProductListing_OnLoad(sender, args);
    }, 250);
};

CategorisedProductListing_Initialise = function() {
    if (typeof LoadSlider == 'function') LoadSlider();
    if (typeof initialiseDefaultButtons == 'function') initialiseDefaultButtons();
    if (typeof initialiseFonts == 'function') initialiseFonts();
};

var customHistoryManager = null;
$(function() {
    CategorisedProductListing_Initialise();


    /* jQuery History Plugin Integration */
    customHistoryManager = new CategorisedProductListing_Hash();

    var originalUrl = window.location.toString();
    var hashIndex = originalUrl.lastIndexOf('#');
    var currentUrl = originalUrl.substring(originalUrl.lastIndexOf('/') + 1, (hashIndex > 0 ? hashIndex : originalUrl.length));

    $.historyInit(ajaxLoad, currentUrl);

    // jQuery History Enabled links
    $('[jQHE]').live('click', function(event) {
        customHistoryManager.onClick(event);
        return false;
    });

    $('[jQHHIPP]').bind('change', function(event) {
        customHistoryManager.onClick(event);
        return false;
    });

    CategorisedProductListing_OnLoad();
});

///
/// jQuery History Plugin Integration
///
/// This hash based history integration is specific to this page, controls and structure
/// DO NO MODIFY
///
/// TODO:
///     D Convert all regular expressions to use XRegExp library for cross-browser compliance
///     - Re-write all regular expressions to have shortest regular expression possible and write some tests
///     D Write functions around getting particular hash values i.e., value, parentValue, name, count and type
///

/* ajax load */
ajaxLoad = function(hash) {
    try {
        //if ($.browser.msie) hash = encodeURIComponent(hash);
        var ajaxManager = ram;
        if (ajaxManager === null) throw new 'Rad Ajax Manager could not be found on this page';
        ajaxManager.AjaxRequest(hash);
    } catch (e) {
        trace(e);
    }
};

/* constructor */
var CategorisedProductListing_Hash = function(inputId, pageInputId, ippInputId) {
    this._inputId = ((typeof inputId != 'undefined' && inputId != null) ? inputId : 'hfSerialisedFilters');
    this._pager = ((typeof pageInputId != 'undefined' && pageInputId != null) ? pageInputId : 'hfCurrentPage');
    this._ipp = ((typeof ippInputId != 'undefined' && ippInputId != null) ? ippInputId : 'hfItemsPerPage');

    this.Action = {
        add: 0,
        remove: 1,
        clear_type: 2,
        clear: 3
    };
    this.Type = {
        filter: 0,
        pager: 1,
        items_per_page: 2
    };

    /* validate object */
    this.validate = function() {
        if ($('input[id=' + this._inputId + ']').length <= 0) throw new 'Required input control not found: hfSerialisedFilters';
    };

    this.onClick = function(event) {
        try {
            // click event handler for jQuery History Enabled content
            // since checkboxes and radio buttons are encapsulated inside <span> tags
            // (and these span tags contain all the relevant attributes), we must find the tag
            // which contains the relevant attributes;

            var target = event.target;
            var tag = target.tagName;

            trace(target);
            trace(tag);

            var type = null;
            var jQHistoryElement = null;

            // check if its paging or items per page control
            if (/select/i.test(tag) || typeof $(target).attr('jQHHP') != 'undefined') {
                if (/select/i.test(tag)) {
                    // items per page
                    type = this.Type.items_per_page;
                    jQHistoryElement = target;
                } else if (typeof $(target).attr('jQHHP') != 'undefined') {
                    // paging
                    type = this.Type.pager;
                    jQHistoryElement = target;
                } else {
                    throw new 'Unknown tag found';
                }
            } else {
                type = this.Type.filter;
                if (/span/i.test(tag) || /a/i.test(tag) || /IMG/i.test(tag)) {
                    jQHistoryElement = target;
                } else if (/input/i.test(tag) || /label/i.test(tag)) {
                    var wrapper = $(target).parent('span')[0];
                    jQHistoryElement = wrapper;
                } else {
                    throw new 'Unknown tag found';
                }
            }

            if (jQHistoryElement == null) {
                throw new 'Relevant jQuery History Element could not be found. (target: {0})'.format(target);
            }

            if (type == null) {
                throw new 'Unknown jQuery History Element type. (target: {0}'.format(target);
            }

            trace(type);

            // check what action to perform
            var action = null;
            if (type == this.Type.filter) {
                // filter controls
                action = this.Action.add;
                if (typeof $(jQHistoryElement).attr('jQHC') != 'undefined') {
                    action = this.Action.clear;
                } else if (typeof $(jQHistoryElement).attr('jQHCT') != 'undefined') {
                    action = this.Action.clear_type;
                } else if (typeof $(jQHistoryElement).attr('jQHR') != 'undefined') {
                    action = this.Action.remove;
                }
            }

            // perform action on hash
            var hash = '';

            if (type == this.Type.filter) {
                if (action == this.Action.add || action == this.Action.remove) {
                    hash = $(jQHistoryElement).attr('jQHHV');
                    if (action == this.Action.remove) this.removeParent(hash);
                    else this.add(hash);
                } else if (action == this.Action.clear_type) {
                    var typeId = $(jQHistoryElement).attr('jQHCT');
                    this.removeType(typeId);
                } else if (action == this.Action.clear) {
                    this.setFilter('');
                } else {
                    throw new 'Unable to perform unknown action: {0}'.format(action);
                }
            } else if (type == this.Type.pager) {
                var page = $(jQHistoryElement).attr('jQHHP'); trace('Changing page to: {0}'.format(page));
                this.changePage(page);
            } else if (type == this.Type.items_per_page) {
                var ipp = $(jQHistoryElement).children(':selected').val(); trace('Changing items per page to: {0}'.format(ipp));
                this.changeItemsPerPage(ipp);
            } else {
                throw new 'Unknown type: {0}'.format(type);
            }

            //don't scroll to top when a category (i.e. furniture type) is clicked
            if ((/-t71-c/.test(hash))) { }
            else {
                scroll(0, 0);
            }

            // load page based on current hash
            trace(this.getHash());
            $.historyLoad(this.getHash());
        } catch (e) {
            trace(e);
        }
    };

    /* get hash value */
    this.getHash = function() {
        try {
            this.validate();
            return 'p={0}&ipp={1}&f={2}'.format(this.current(this.Type.pager), this.current(this.Type.items_per_page), escape(this.current(this.Type.filter)));
        } catch (e) {
            trace(e);
        }
    }

    /* change the page */
    this.changePage = function(page) {
        try {
            this.validate();
            $('input[id=' + this._pager + ']')[0].value = page;
        } catch (e) {
            trace(e);
        }
    };

    /* change items per page */
    this.changeItemsPerPage = function(ipp) {
        try {
            this.validate();
            $('input[id=' + this._ipp + ']')[0].value = ipp;
            this.changePage(1);
        } catch (e) {
            trace(e);
        }
    };

    /* returns current hash value */
    this.current = function(type) {
        try {
            this.validate();

            if (type == this.Type.filter) {
                return $('input[id=' + this._inputId + ']')[0].value;
            } else if (type == this.Type.items_per_page) {
                return $('input[id=' + this._ipp + ']')[0].value;
            } else if (type == this.Type.pager) {
                return $('input[id=' + this._pager + ']')[0].value;
            } else {
                throw new 'Invalid type: {0}'.format(type);
            }
        } catch (e) {
            trace(e);
        }

        return '';
    };

    /* sets the current hash value */
    this.setFilter = function(hash) {
        try {
            this.validate();
            $('input[id=' + this._inputId + ']')[0].value = hash;
            this.changePage(1);
        } catch (e) {
            trace(e);
        }
    };

    /* adds given hash value to the current hash value */
    this.add = function(hash) {
        try {
            this.validate();
            // need to filter out certain types of hash values (i.e., prices) and remove all previous
            // hash values of the same type before adding a new, and updated, hash value
            // FIXME: only remove this type if the hash being added is of this type
           
            if (!this.contains(hash))
                $('input[id=' + this._inputId + ']')[0].value += hash;

            this.changePage(1);
        } catch (e) {
            trace(e);
        } finally {
            return this.current(this.Type.filter);
        }
    };

    /* returns true if given hash value is already in the current value */
    this.contains = function(hash) {
        var currentValue = this.current(this.Type.filter);
        return (currentValue.indexOf(hash) > -1);
    };

    /* remove given hash value from the current hash value */
    this.remove = function(hash) {
        try {
            if (hash.search(/-c([^_]+)_/) > -1) { // since count is always different, we disregard count section
                hash = hash.substring(0, hash.search(/-c([^_]+)_/));
                var regexString = hash + '-c(\\d+)_';
                regexString = regexString.replace('|', '\\|');
                var regex = new RegExp(regexString);
                var currentValue = this.current(this.Type.filter);
                currentValue = currentValue.replace(regex, '');
                this.setFilter(currentValue);
                this.changePage(1);
            }
        } catch (e) {
            trace(e);
        } finally {
            return this.current(this.Type.filter);
        }
    };

    /* remove the given hash and all other hash values that are regarded as its parents */
    this.removeParent = function(hash) {
        try {
            // 1. extract parent value from the given hash
            // 2. find the hash value which has its value set to extract parent value
            // 3. remove the given hash value
            // 4. run removeParent on the hash value found in number 2
            this.validate();

            // 1. find the parent value from given hash
            var parentValue = null;
            var _parentRegex = '_v([^-]+)-pv';
            var parentRegex = new RegExp(_parentRegex, "i");
            var parentResult = parentRegex.exec(hash);
            if (typeof parentResult != 'undefined' && parentResult != null) parentValue = parentResult[parentResult.length - 1];
            if (parentValue == null) throw new 'Parent value could not be extract from the given hash value: {0}'.format(hash);

            // we need current value from here
            var currentValue = this.current(this.Type.filter);

            // 2. find parent hash
            var parentHash = null;
            var _parentHashRegex = '_v[^-]+-pv{0}-n[^_]+_'.format(parentValue); // regex to extract parent value
            var parentHashRegex = new RegExp(_parentHashRegex, 'i');
            var parentHashResult = parentHashRegex.exec(currentValue);
            if (typeof parentHashResult != 'undefined' && parentHashResult != null) parentHash = parentHashResult[parentHashResult.length - 1];

            // 3. remove the given hash value
            this.remove(hash);

            // 4. if parentHash is not null, run removeParent on it
            if (parentHash != null) this.removeParent(parentHash);
        } catch (e) {
            trace(e);
        }
    };

    /* remove given type */
    this.removeType = function(typeId) {
        try {
            var _typeRegex = '_[^_]+-t{0}-[^_]+_'.format(typeId);
            var typeRegex = new RegExp(_typeRegex);
            var currentValue = this.current(this.Type.filter);
            currentValue = currentValue.replace(typeRegex, '');
            this.setFilter(currentValue);
        } catch (e) {
            trace(e);
        } finally {
            return this.current(this.Type.filter);
        }
    };

    /* extract names of the current hash values */
    this.title = function() {
        var title = '';
        try {
            this.validate();
            var currentValue = this.current(this.Type.filter);
            // we're only interested in the captured group <name>
            // this will filter out names like: '15 - 20' because of the [^_] match if you wish to include them
            // then replace the regular expression with: '-n(?<name> .+?)-t'. this is a non-greedy way of grabbing names
            var _nameRegex = '-n(?<name> [^-]+)-t';
            var xnameRegex = new XRegExp(_nameRegex, 'ix');

            // see doc: http://xregexp.com/api/
            xnameRegex.forEachExec(currentValue, function(match) {
                title += '{0}{1}'.format((title == '' ? '' : ' - '), (match[match.length - 1]));
            });
        } catch (e) {
            trace(e);
        } finally {
            return escape(title);
        }
    };

    /* extract the last filter */
    this.lastFilterName = function() {
        var title = '';
        try {
            this.validate();
            var currentValue = this.current(this.Type.filter);
            // we're only interested in the captured group <name>
            // this will filter out names like: '15 - 20' because of the [^_] match if you wish to include them
            // then replace the regular expression with: '-n(?<name> .+?)-t'. this is a non-greedy way of grabbing names
            var _nameRegex = '-n(?<name> [^-]+)-t2-';
            var xnameRegex = new XRegExp(_nameRegex, 'ix');

            // see doc: http://xregexp.com/api/
            xnameRegex.forEachExec(currentValue, function(match) {
                title = match[match.length - 1];
            });
        } catch (e) {
            trace(e);
        } finally {
            return title;
        }
    };

    this.validate();
};

function ToggleCategoryState(ImageID, LabelID, UnSelectedFileEnding, SelectedFileEnding, SelectedClassName) {

    var img = document.getElementById(ImageID);
    var lbl = document.getElementById(LabelID);
    var currentState;
    var newState;

    if (img.src.indexOf(SelectedFileEnding) >= 0) {
        currentState = SelectedFileEnding;
        newState = UnSelectedFileEnding;
        lbl.className = '';
    }
    else{
        currentState = UnSelectedFileEnding;
        newState = SelectedFileEnding;
        lbl.className = SelectedClassName;
    }

    img.src = img.src.replace(currentState, newState);
    
}
