﻿   /**
    * ironMountain.js
    * Containts methods / functions / object used throughout the entire public site
    *
    * @requires none
    * @namespace im
    * @version 1.7
    */
    
   /**
    * Registers 'im' as a window namespace
    * Creates the im.namespace(@param) namespace function.
    */
    if (typeof im == 'undefined') { var im = {}; } 
    im.namespace = function() { var a = arguments, e = null, c, b, d; for (c = 0; c < a.length; c++) { d = a[c].split('.'); e = im; for (b = (d[0] == 'im') ? 1 : 0; b < d.length; b++) { e[d[b]] = e[d[b]] || {}; e = e[d[b]] } } return e};

   /**
    * Set namespaces for entire site
    */
    im.namespace('root');
    im.namespace('search');
    im.namespace('menu');
    im.namespace('basket');
    im.namespace('validate');
    im.namespace('root.ajax');

   /**
    * Global vars - Short cut methods
    */
    var Dom = YAHOO.util.Dom;
    var Event = YAHOO.util.Event; 
    var $ = Dom.get;

   /**
    * Core
    * @namespace im.root
    */
    im.root = {

        /**
        * The timer object used by im.root.scroll_window()
        */
        scroll_window_t: null,

        /**
        * Safely adds a function to the window onload handler
        * @param func {Object} The function to add to the queue
        */
        registerSafeLoad: function(func) {
            var oldonload = window.onload;
            if (typeof window.onload != 'function') {
                window.onload = func;
            } else {
                window.onload = function() {
                    if (oldonload) {
                        oldonload();
                    }
                    func();
                }
            }
        },

        /**
        * Checks for real mouse leave / mouse enter
        * @param e {Event} The event that took place
        * @param handler {Object} The dom object which executed the event
        */
        e_m: function(e, handler) {
            if (e.type != 'mouseout' && e.type != 'mouseover')
                return false;

            var reltg = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout'
                ? e.toElement : e.fromElement;

            while (reltg && reltg != handler) {
                reltg = reltg.parentNode;
            }

            return (reltg != handler);
        },

        /**
        * Smoothly scrolls the window to the top
        */
        scroll_window: function() {
            if (parent.document.body.scrollTop != 0 || parent.document.documentElement.scrollTop != 0) {
                parent.window.scrollBy(0, -20);
                im.root.scroll_window_t = setTimeout('im.root.scroll_window()', 20);
            }
            else {
                clearTimeout(im.root.scroll_window_t);
            }
        },

        /**
        * Shows a confirmation message
        * @param msg {String} The message to show in the confirmation box
        */
        cfirm: function(msg) {
            return confirm(msg);
        },

        /**
        * Shop By Brand functions
        */
        shopByBrand: function() {
            var obj = $('brandAreaContent');
            var up = $('brandAreaContent_up');
            var down = $('brandAreaContent_down');
            var c_int = null;

            Event.on(down, 'mouseover', function(e) {
                var el = $(obj);
                c_int = setInterval(function() {
                    el.scrollTop = (el.scrollTop + 2);
                }, 4);
            });

            Event.on(down, 'mouseout', function(e) {
                window.clearInterval(c_int);
                c_int = null;
            });

            Event.on(up, 'mouseover', function(e) {
                var el = $(obj);
                c_int = setInterval(function() {
                    el.scrollTop = (el.scrollTop - 2);
                }, 4);
            });

            Event.on(up, 'mouseout', function(e) {
                window.clearInterval(c_int);
                c_int = null;
            });
        }
    };


    /**
    * Search
    * @namespace im.search
    */
    im.search = {

        /**
        * Register the search auto complete
        */
        registerSearch: function() {

            /**
            * Register a Data Source for the AutoComplete
            */
            var ds = new YAHOO.util.XHRDataSource('/_common/services/search.aspx');

            /**
            * DataSource properties
            */
            ds.responseType = YAHOO.util.XHRDataSource.TYPE_JSON;

            /**
            * Data Source response schema
            */
            ds.responseSchema = {
                resultsList: 'ResultSet.Result',
                fields: ['ProductName', 'ProductId', 'ProductInfo']
            };

            /**
            * Register the AutoComplete
            */
            var ac = new YAHOO.widget.AutoComplete('ac-text-search', 'ac-results-container', ds);

            /**
            * AutoComplete properties
            */
            ac.animVert = false;
            ac.minQueryLength = 3;
            ac.typeAhead = false;
            ac.forceSelection = false;
            ac.allowBrowserAutocomplete = false;
            ac.resultTypeList = false;
            ac.useIFrame = true;

            /**
            * Custom result formatting
            */
            ac.formatResult = function(oResultData, sQuery, sResultMatch) {
                return ('<div class=\"yui-ac-result-name\">' + oResultData.ProductName + '</div>'
                    + '<div class=\"yui-ac-result-info\">' + oResultData.ProductInfo + '</div>');
            };

            /**
            * Overridable
            * Converts an autocomplete query into a request
            */
            ac.generateRequest = function(s) {
                return '?ac=true&q=' + s;
            };

            /**
            * Overridable.
            * Custom events
            */
            var itemSelectEvent = function(sType, aArgs) {
                window.location = '/product/detail/?p=' + (aArgs[2].ProductId);
            }

            var dataRequestEvent = function(oSelf, oQuery) {
                $('ac-load').style.display = 'block';
            }

            var dataReturnEvent = function(oSelf, oQuery, aResults) {
                $('ac-load').style.display = 'none';
            }

            /**
            * Register custom events
            */
            ac.dataRequestEvent.subscribe(dataRequestEvent);
            ac.dataReturnEvent.subscribe(dataReturnEvent);
            ac.itemSelectEvent.subscribe(itemSelectEvent);

            /**
            * Register the DataSource and AutoComplete
            */
            return { oDS: ds, oAC: ac };
        },

        doBasicSearch: function() {
            var url = '/search/search.aspx?a=false&q='
                + $('ac-text-search').value.replace(' ', '+');

            window.location = url;
        },

        doAdvancedSearch: function() {
            var url = '/search/search.aspx?a=true&br=' + $('search-form-advanced-br').value;
            url += '&se=' + $('search-form-advanced-se').value + '&q=';
            url += $('search-form-advanced-q').value.replace(' ', '+');

            window.location = url;
        },

        registerSearchType: function(type) {
            $('searchType').value = type;

            if (type == 'a') {
                $('search-form-advanced').style.display = 'block';
            }
            else {
                $('search-form-advanced').style.display = 'none';
            }
        },

        submitSearch: function() {
            if ($('searchType').value == '' || $('searchType').value == 'b') {
                this.doBasicSearch();
            }
            else {
                this.doAdvancedSearch();
            }
        }
    };
    
   /**
    * Ajax
    * @namespace im.root.ajax
    */
    im.root.ajax = {

       /**
        * Returns a cross browser XMLHttp object
        */
        _createTransport: function() {
            if (typeof XMLHttpRequest != "undefined") {
                return new XMLHttpRequest();
            }
            else if (typeof ActiveXObject != "undefined") {
                var http = null;
                try {
                    http = new ActiveXObject("MSXML2.XmlHttp.6.0");
                    return http;
                }
                catch (ex) {
                    try {
                        http = new ActiveXObject("MSXML2.XmlHttp.3.0");
                        return http;
                    }
                    catch (ex2) {
                        throw Error("Cannot create XHR object");
                    }
                }
            }
        },

       /**
        * Executes an AJAX Request
        * @param url {String} The url to make a request oo
        * @param callback {Object} The object containing success / failure methods
        */
        doRequest: function(url, callback) {
            var _t = this._createTransport();
            _t.open('get', url, true);
            _t.onreadystatechange = function() {
                if (_t.readyState == 4) {
                    if (_t.status == 200) {
                        callback.success(_t);
                    }
                }
            }
            _t.send(null);
        }
    };
    
   /**
    * Basket
    * @namespace im.basket
    */
    im.basket = {

        /**
        * The service path of the basket
        */
        service_path: '/_common/services/basket.aspx',

        /**
        * Returns a current users basket
        */
        get: function() {
            var url = this.service_path + '?method=get';
            var callback = {
                success: function(o) {
                    if (($('basket-contents') != null)) {
                        $('basket-contents').innerHTML = o.responseText;
                    }
                }
            };

            im.root.ajax.doRequest(url, callback);
        },

        /**
        * Adds a product to the basket
        * @param p {Int} The product id
        * @param q {Object} The object to find the quantity value from, if null, defaults to 1
        */
        add: function(p, q) {
            if (q != null)
                q = $(q).value;
            else
                q = 1;

            var url = this.service_path + '?method=add&p=' + p + '&q=' + q;
            var callback = {
                success: function(o) {
                    im.basket.get();
                }
            }

            im.root.ajax.doRequest(url, callback);

            return false;
        }
    };
    
   /**
    * Validate
    * @namespace im.validate
    */
    im.validate = {
       /**
        * Whether or not we can validate the page
        */
        _continue: function() {
            if (($('pErrorMessage') == null) && ($('lErrorMessage') == null))
                return false;
            return true;
        },

       /**
        * Shows an error message on the page
        * @param m {String} The error message to show
        */
        _showError: function(m) {
            Dom.setStyle($('pErrorMessage'), 'display', 'block');
            $('lErrorMessage').innerHTML = m;
        },
        
       /**
        * Validates a text box
        * @param obj {Object} The text box to validate
        * @param value {String} The default value, what the obj.value cannot be
        * @param msg {String} The error message to show if the validation fails
        */
        txt: function(obj, value, msg) {
            if (im.validate._continue()) {
                if (($(obj).value == value)) {
                    im.root.scroll_window();
                    im.validate._showError(msg);

                    return false;
                }
            }
            return true;
        },

       /**
        * Validates a number
        * @param obj {Object} The text box to validate
        * @param value {String} Not used, left for backward compatibility
        * @param msg {String} The error message to show if the validation fails
        */
        num: function(obj, value, msg) {
            if (im.validate._continue()) {
                if (isNaN($(obj).value)) {
                    im.root.scroll_window();
                    im.validate._showError(msg);

                    return false;
                }
            }
        },

       /**
        * Validates a drop down list
        * @param obj {Object} The drop down list to validate
        * @param value {String} The default value, what the obj.value cannot be
        * @param msg {String} The error message to show if the validation fails
        */
        ddl: function(obj, value, msg) {
            if (im.validate._continue()) {
                if (($(obj).value == value)) {
                    im.root.scroll_window();
                    im.validate._showError(msg);

                    return false;
                }
            }
        }
    };

   /**
    * Sub menu
    * @namespace im.menu
    */
    im.menu = {
       /**
        * The time until a menu closes
        */
        timeout: 500,
        
       /**
        * The timer object until close
        */
        closetimer: 0,
        
       /**
        * The current menu item open
        */
        ddmenuitem: 0,

       /**
        * Opens a sub menu
        * @param id {Int} The catalogue id sub menu to open
        */
        open: function(id) {
            im.menu.cancelCloseTime();
            if (im.menu.ddmenuitem) {
                Dom.setStyle(im.menu.ddmenuitem, 'visibility', 'hidden');
            }

            im.menu.ddmenuitem = Dom.get('im-sub-menu-' + id);
            Dom.setStyle(im.menu.ddmenuitem, 'visibility', 'visible');
            Dom.setStyle(im.menu.ddmenuitem, 'top', (Dom.getXY('main-menu-' + id)[1] + 40) + 'px');
            Dom.setStyle(im.menu.ddmenuitem, 'left', (Dom.getXY('main-menu-' + id)[0]) + 'px');
        },
        
       /**
        * Closes the current open sub menu
        */
        close: function() {
            if (im.menu.ddmenuitem) {
                Dom.setStyle(im.menu.ddmenuitem, 'visibility', 'hidden');
            }
        },

       /**
        * Sets the close timer
        */
        closeTime: function() {
            im.menu.closetimer = window.setTimeout(im.menu.close, im.menu.timeout);
        },

       /**
        * Cancels the close timer
        */
        cancelCloseTime: function() {
            if (im.menu.closetimer) {
                window.clearTimeout(im.menu.closetimer);
                im.menu.closetimer = null;
            }
        }
    };

   /**
    * Register a function on window load
    */
    im.root.registerSafeLoad(function() {
        // populate the basket
        im.basket.get();

        // register the search auto complete
        im.search.registerSearch();

        // shop by brand.
        im.root.shopByBrand();
    });