﻿// expanding motoring refine list - shira
$(function() {
    if ($('label.refine-type-title').text().indexOf('Motoring') > -1) {
        $('ul#property').append('<a href="#" id="showmoreoptions" class="lui-button">Show more options</a>');
        hideExpanded();
    }
    $('#showmoreoptions').toggle(function() {
        showExpanded();
    }, function() {
        hideExpanded();
    });
    
});

function hideExpanded(){
	$('ul#property>li:gt(1)').slideUp(200);
	$('#showmoreoptions').text('Show more options');	
};
function showExpanded(){
	$('ul#property>li:gt(1)').slideDown(200);
	$('#showmoreoptions').text('Show fewer options');
}
//end of expanding motoring refine list - shira
	
	
(function() {
    var seo_copy = {
        config: {
            id: 'category_info'
        },
        init: function() {
            try {
                Dom.get(this.config.id).style.display = 'none';
            } catch (ex) {
                // Do Nothing
            };
        }
    };
    Event.onAvailable(seo_copy.config.id, seo_copy.init, seo_copy, true);

    var build_skyScraper = {
        config: {
            page_id: "search_results",
            page_className: "int"
        },
        init: function() {
            var _showBanner = Dom.get(this.config.page_id).className !== this.config.page_className;
            if (Dom.getViewportWidth() > LOOT.constant.skyscraper_screen_size && _showBanner) {
                var _parent = Dom.get('bd'),
                    _skyScraper = new LOOT.widget.banner(_parent);

                _skyScraper.show();
            };
        }
    }
    Event.onDOMReady(build_skyScraper.init, build_skyScraper, true);

    var validate_postcode = {
        config: {
            postcode_input_id: 'location_refine_value'
        },
        init: function() {
            if (POSTCODE_VALID !== null) {
                var _postcode_data = JSON.parse(POSTCODE_VALID);

                if (POSTCODE_VALID && _postcode_data.Status == 0) {
                    var _self = this,
                        _errorPanel,
                        _h = LOOT.constant.error.messages.postcode,
                        _msg = 'Sorry we didn\'t recognise your postcode (<strong>' + _postcode_data.Postcode + '</strong>). Please enter a valid UK postcode.';
                    _self.postcode_input = Dom.get(this.config.postcode_input_id);

                    _self.errorPanel = new LOOT.panel.ModalDialogRounded(_h, {
                        close: false
                    });

                    _errorPanel = this.errorPanel;
                    _errorPanel._buttons = [];
                    _errorPanel.setBody(_msg);

                    _errorPanel.showEvent.subscribe(function() {
                        if (this._buttons.length == 0) {
                            this._buttons[0] = new YAHOO.widget.Button({
                                type: 'push',
                                label: 'Ok',
                                container: 'footer_buttons'
                            });

                            this._buttons[0].on('click', function() {
                                _errorPanel.hide();
                                _errorPanel.setBody('');
                                Dom.removeClass(Selector.query('body'), 'yui-skin-sam');
                                _self.postcode_input.focus();
                            });
                        };
                    }, _self.errorPanel, true);

                    Dom.addClass(Selector.query('body'), 'yui-skin-sam');
                    _self.errorPanel.show();
                };
            };
        }
    }
    Event.onDOMReady(validate_postcode.init, validate_postcode, true);

    var multiple_locations = {
        config: {
            trigger_id: 'info_message'
        },
        init: function() {
            var _link = Selector.query('p a', this.config.trigger_id, true),
                _linkX, _linkY,
                _offset = 15;

            this.select = Selector.query("select#multiple_locations_list", this.config.trigger_id, true);

            if (this.select) {
                try {
                    var _parent = this.select.parentNode;

                    _link.style.display = 'inline';
                    _linkX = Dom.getX(_link);
                    _linkY = Dom.getY(_link);

                    this.popup = new YAHOO.widget.Panel("lui_panel_info", {
                        xy: [_linkX + _link.offsetWidth + _offset, _linkY - _offset],
                        width: "280px",
                        draggable: false,
                        visible: false,
                        zIndex: 3
                    });
                    this.popup.setHeader('<div class="tl"></div><span>Choose a location:</span><div class="tr"></div>');
                    this.popup.setBody(this.build_list(this.select));
                    this.popup.setFooter('<div class="bl"></div><span></span><div class="br"></div>');
                    this.popup.render(this.config.trigger_id);

                    _parent.removeChild(this.select);

                    Event.addListener(_link, "click", this.handle_click, this, true);
                } catch (ex) {
                    // Do Nothing
                };
            };
        },
        handle_click: function(ev) {
            this.popup.show();
        },
        build_list: function(el) {
            var _html,
                _kyd = Selector.query('p em', this.config.trigger_id, true).innerHTML.replace(/\"/g, ''),
                _url = document.URL;

            // Build the list of locations
            _html = '<ul id="locations_list">';
            for (var i = 0; i < el.options.length; i++) {
                var _option = el.options[i],
                    _className = '';

                if (i === 0) {
                    _className = ' class="first"';
                } else if (i === el.options.length - 1) {
                    _className = i % 2 ? ' class="even last"' : ' class="last"';
                } else if (i % 2) {
                    _className = ' class="even"';
                };

                var findText = ('loc=' + _kyd).replace(' ', '+');
                var replaceText = ('loc=' + _option.text)
									.replace(/ /g, '+')
									.replace(/%20/g, '+')
									.replace(/,/g, '%2c');

                var href = _url.replace(findText, replaceText);
                var link = '<a href="' + href + '">' + _option.text + '</a>';

                _html += '<li' + _className + '>' + link + '</li>';
            };
            _html += '</ul>';
            // add the span element for adding the knob
            _html += '<span class="knob"></span>';

            return _html;
        }
    };
    Event.onAvailable(multiple_locations.config.trigger_id, multiple_locations.init, multiple_locations, true);

    var property_list = {
        config: {
            trigger_id: 'category-props',
            webservice: {
                path: LOOT.constant.path.webservice,
                name: LOOT.constant.webservice.category.property,
                method: '/HandleCategoryPropertyChange'
            },
            acConfig: function(f, c) {
                return {
                    forceSelection: f,
                    autoHighlight: false,
                    prehighlightClassName: "yui-ac-prehighlight",
                    useShadow: true,
                    animSpeed: .1,
                    queryDelay: 0,
                    minQueryLength: 0,
                    animVert: .01,
                    typeAhead: true,
                    typeAheadDelay: 0,
                    maxResultsDisplayed: c > 10 ? c : 10
                }
            }
        },
        init: function() {
            this.propertyDS = [];
            var _selects = Selector.query('#' + this.config.trigger_id + ' li select'),
                _zCounter = 9000 + _selects.length;
            for (var i = 0; i < _selects.length; i++) {
                this.autocomplete(_selects[i], _zCounter);
                _zCounter--;
            };
        },
        autocomplete: function(el, counter) {
            var _self = property_list,
                _options = [], _propertyDS = {},
                _categoryId = LOOT_category_id,
                _propertyTypeId = (function() {
                    var _id = el.name;
                    return _id.split('_')[_id.split('_').length - 1];
                })();

            for (var i = 0; i < el.options.length; i++) {
                var tmpObj = {};
                tmpObj.name = el.options[i].text;
                tmpObj.id = el.options[i].value;
                _options.push(tmpObj);
            };

            try {
                var _parent = el.parentNode,
                    _listLocked = el.className.toLowerCase().contains('locked'),
                    _hasChildren = el.className.toLowerCase().contains('parent'),
                    _acCombo = document.createElement('div');
                _acCombo.className = 'lui-combo-box';
                _acCombo.id = el.name + '_combo';
                var _input = document.createElement('input');
                _input.name = el.name;
                _input.id = el.name;
                if (el.className) { _input.className = el.className; };
                _input.value = el.options[el.selectedIndex].text;
                var _button = document.createElement('span');
                _button.id = el.name + '_button';
                _button.className = 'lui-autocomplete-toggle';
                var _div = document.createElement('div');
                _div.id = el.name + '_container';

                if (YAHOO.env.ua.ie) {
                    // Only add zindex for IE due to a bug in ie.
                    el.parentNode.style.position = 'relative';
                    el.parentNode.style.zIndex = counter;
                };
                Dom.insertAfter(_acCombo, el);
                _acCombo.appendChild(_input);
                Dom.insertAfter(_button, _input);
                Dom.insertAfter(_div, _button);
                if (!YAHOO.env.ua.ie > 0) {
                    _div.style.width = el.clientWidth > _div.clientWidth ? el.clientWidth + 'px' : _div.style.width;
                };

                var _inputDS = new YAHOO.util.LocalDataSource(_options);
                _inputDS.responseSchema = { fields: ["name", "id"] };
                var _inputAC = new YAHOO.widget.AutoComplete(_input, _div, _inputDS, _self.config.acConfig(_listLocked, _options.length));
                _inputAC.resultTypeList = false;

                _propertyDS.id = el.name.split('_')[el.name.split('_').length - 1];
                _propertyDS.autocomplete = _inputAC;

                _self.propertyDS.push(_propertyDS);

                try { // try to add toggle buttons to autocomplete controls
                    var _toggleButton = new YAHOO.widget.Button({ container: _button.id });
                    var _toggle = function(ev) {
                        try {
                            if (!Dom.hasClass(_button, "open")) {
                                Dom.addClass(_button, "open")
                            };
                            if (_inputAC.isContainerOpen()) {  // Is open
                                _inputAC.collapseContainer();
                            } else {                        // Is closed
                                _inputAC.getInputEl().focus();    // Needed to keep widget active
                                setTimeout(function() {         // For IE
                                    _inputAC.sendQuery("");
                                }, 0);
                            };
                        } catch (ex) {
                            // Do Nothing
                        };
                    };
                    _toggleButton.on("click", _toggle);
                    _inputAC.containerCollapseEvent.subscribe(function() { Dom.removeClass(_button, "open") });
                } catch (ex) {
                    // Remove button if it fails - TODO
                };

                _inputAC.textboxBlurEvent.subscribe(function(sType, aArgs) {
                    var _myAC = aArgs[0], // reference back to the AC instance 
                        _textBoxValue = _myAC._elTextbox.value,
                    /*
                    To get the listItemId had to itterate through the dataSource liveData to match the text entered
                    in the input with the text values in the live data. The Id is required to get the child properties.
                    */
                        _listItemId = (function() {
                            var _returnData = 0;
                            for (var i = 0; i < _myAC.dataSource.liveData.length; i++) {
                                var _data = _myAC.dataSource.liveData[i].name.toLowerCase().replace(' ', '');
                                if (_data == _textBoxValue.toLowerCase().replace(' ', '')) {
                                    _returnData = _myAC.dataSource.liveData[i].id;
                                };
                            };
                            return _returnData;
                        })();

                    if (_hasChildren) {
                        _self.get_child_properties(_categoryId, _propertyTypeId, _listItemId);
                    };
                });

                _inputAC.itemSelectEvent.subscribe(function(sType, aArgs) {
                    var _myAC = aArgs[0], // reference back to the AC instance 
                        _elLI = aArgs[1], // reference to the selected LI element 
                        _oData = aArgs[2]; // object literal of selected item's result data

                    if (!_oData) {
                        _myAC._elTextbox.value = 'Any';
                    };
                    if (_hasChildren) {
                        _self.get_child_properties(_categoryId, _propertyTypeId, _oData.id);
                    };
                });

                // If one of the options has been selected display different control
                if (!el.options[0].defaultSelected) {
                    var _propertyType = Dom.getPreviousSibling(el) !== null ? Dom.getPreviousSibling(el) : Dom.getPreviousSibling(el.parentNode.parentNode);
                    var _selectedProperty = document.createElement('span'); // create a span element, with the selected value inside
                    _selectedProperty.id = 'selected_property_' + _propertyTypeId;
                    _selectedProperty.className = 'selected-property';
                    _selectedProperty.appendChild(document.createTextNode(_input.value));
                    var _selectedPropertyChange = document.createElement('a');
                    _selectedPropertyChange.appendChild(document.createTextNode('change'));
                    _selectedPropertyChange.href = 'javascript: void(0);';
                    if (_propertyType !== null) {
                        _selectedPropertyChange.title = 'change \'' + _input.value + '\' to another ' + _propertyType.innerHTML;
                    };
                    _selectedProperty.appendChild(_selectedPropertyChange);

                    Dom.insertAfter(_selectedProperty, _acCombo);
                    Dom.setStyle(_acCombo, 'display', 'none');

                    Event.addListener(_selectedPropertyChange, "click", function() {
                        Dom.setStyle(_acCombo, 'display', 'block');
                        Dom.setStyle(_selectedProperty, 'display', 'none');
                        if (_hasChildren) {
                            _self.get_child_properties(_categoryId, _propertyTypeId, 0, function(o) {
                                var _self = property_list,
                                    _JSON = JSON.parse(o.responseText);

                                for (var i = 0; i < _JSON.Items.length; i++) {
                                    var _id = _JSON.Items[i].Id
                                    Dom.setStyle(Dom.get('property_item_' + _id + '_combo'), 'display', 'block');
                                    Dom.setStyle(Dom.get('selected_property_' + _id), 'display', 'none');
                                };

                            });
                        }
                    });
                };

                // last thing to so is remove the original select box
                _parent.removeChild(el);
            } catch (ex) {
                // Do Nothing
            };
        },
        get_child_properties: function(catId, propId, listId, callback) {
            var _self = property_list,
                _url = _self.config.webservice.path + _self.config.webservice.name + _self.config.webservice.method,
                _params = 'categoryId=' + catId + '&listType=search&propertyTypeId=' + propId + '&listItemId=' + listId + '&type=json',
                _callback = {
                    success: callback || _self.handle_ac_response,
                    failure: function(o) {
                        var _JSON = JSON.parse(o.responseText);

                        //console.log(o, _JSON);
                    }
                };
            Connect.asyncRequest('POST', _url, _callback, _params);
        },
        handle_ac_response: function(obj) {
            var _self = property_list,
                _JSON = JSON.parse(obj.responseText);

            for (var i = 0; i < _JSON.Items.length; i++) {
                _self.update_autocomplete(_JSON.Items[i]); // update each of the autocomplete properties that are children
            };
        },
        update_autocomplete: function(obj) {
            var _self = property_list, _newDS = null, _newDsLength,
                _propertyInput = Dom.get('property_item_' + obj.Id),
                _toggleButton = Dom.get('property_item_' + obj.Id + '_button'); // get a reference to the toggle button for the property control

            /* 
            If the child property has a 0 length list then assume there is no list,
            remove the toggle button and let user free type into the input
            */
            if (obj.List.ListItems.length <= 1) {
                Dom.setStyle(_toggleButton, 'display', 'none');
            } else {
                Dom.setStyle(_toggleButton, 'display', 'inline');
                // if there is a list create a new dataSource out of it
                var _dataSource = [], _newDS;

                for (var i = 0; i < obj.List.ListItems.length; i++) {
                    var _tmpObj = {};

                    _tmpObj.Text = obj.List.ListItems[i].Text;
                    _tmpObj.Value = obj.List.ListItems[i].Value;
                    _tmpObj.Name = obj.List.Name;

                    _dataSource.push(_tmpObj);
                };

                _newDS = new YAHOO.util.LocalDataSource(_dataSource);
                _newDS.responseSchema = { fields: ["Text", "Value", "Name"] };
                _newDsLength = _newDS.liveData.length;
            };
            /*
            Iterate through the current autocomplete controls and match the child property
            using its id, then clear current value and change dataSource if necessary
            */
            for (var i = 0; i < _self.propertyDS.length; i++) {
                if (obj.Id == _self.propertyDS[i].id) {
                    var _childAC = _self.propertyDS[i].autocomplete;
                    if (obj.List.ListItems.length > 1) {
                        _childAC._elTextbox.value = 'Any';
                        _childAC.maxResultsDisplayed = _newDsLength;
                        if (_newDS) {
                            _childAC.dataSource = _newDS;
                        };
                    } else {
                        _childAC.dataSource = null;
                        _childAC._elTextbox.value = '';
                    };
                };
            };
        }
    };
    Event.onAvailable(property_list.config.trigger_id, property_list.init, property_list, true);
    
    var property_sliders = {
        config: {
            selectors: {
                propContainers: '.results-list .properties',
                propLists: '.results-list .property-list'
            }
        },
        init: function() {
            this.loader = null;
            this.propLists = Selector.query(this.config.selectors.propLists);
            this.containerWidth = Selector.query(this.config.selectors.propContainers, document, true).offsetWidth;

            if (this.propLists.length > 0) {
                this.scrollers = {};
                this.load_scroller();
            };
        },
        set_container_width: function(val) {
            this.containerWidth = val; //??
        },
        load_scroller: function() {
            var _self = this;

            if (_self.loader == null) {
                _self.loader = new YAHOO.util.YUILoader({
                    require: ['slider'],
                    base: '/content/script/lib/yui/2.8.0/',
                    //filter: "DEBUG", 	//use debug versions
                    onSuccess: function() {
                        for (var i = 0; i < _self.propLists.length; i++) {
                            try {
                                var _list = _self.propLists[i], _parent = _self.propLists[i].parentNode,
                                _listWidth = _list.offsetWidth, _containerWidth = _self.containerWidth,
                                _listObj = new Element(_list),
                                _parentObj = new Element(_parent);

                                if (_listWidth >= _containerWidth) {
                                    _parentObj.addClass('scroller');
                                    _self.build_scroller(_parent.id, _listWidth, _containerWidth);
                                };
                            } catch (ex) {
                                console.log(ex);
                            };
                        };
                    },
                    onFailure: function(o) {
                        Dom.removeClass(Selector.query(_self.config.selectors.propContainers), 'scroller');
                        LOOT.util.log(o);
                    }
                });
                _self.loader.insert(null, 'js');
            };
        },
        build_scroller: function(id, elWidth, conWidth) {
            var _self = this,
                _scrollerId = id.split('_')[0];

            try {
                Dom.replaceClass(id, 'scroller', 'lui-scroller');
                var _thumbWidth = Dom.get(id + '_thumb').offsetWidth;
                _thumbWidth = conWidth - (elWidth - conWidth);

                Dom.setStyle(id + '_thumb', 'width', _thumbWidth + 'px');

                _self.scrollers[_scrollerId] = YAHOO.widget.Slider.getHorizSlider(id + '_bg', id + '_thumb', 0, (conWidth - _thumbWidth) - 2);
                _self.scrollers[_scrollerId].subscribe("change", function(val) {
                    _self.update_scroller(id, val, elWidth, conWidth);
                });
            } catch (ex) { LOOT.util.log(ex); };
        },
        update_scroller: function(id, val, elWidth, conWidth) {
            var _overlapWidth = (elWidth - conWidth) - 2,
                _ratio = _overlapWidth / conWidth,
                _listEl = Dom.get(id + '_list');
            // Move the list element depending on how much the slider has moved
            Dom.setStyle(_listEl, 'left', (val * -1) + 'px');
        }
    };
    Event.onDOMReady(property_sliders.init, property_sliders, true);

    var star_ad = {
        config: {
            trigger_id: 'results',
            saved_container: 'save',
            saved_class: 'starred',
            starred_ad_count_class: 'starred-ad-count'
        },
        init: function() {
            this.timer = new Array();
            var _results = Dom.getElementsByClassName(this.config.saved_container);
            this.stars = new Array();

            for (var i = 0; i < _results.length; i++) {
                var _d = _results[i];
                var _fc = Dom.getFirstChild(_d);
                this.stars.push(_fc);
            };
            Event.addListener(this.stars, "click", star_ad.handle_click, star_ad, true);
            this.counters = Dom.getElementsByClassName(this.config.starred_ad_count_class);
        },
        handle_click: function(ev) {
            var _tar = Event.getTarget(ev);
            var _message_box;

            if (_message_box) {
                _message_box.hide();
            };
            if (star_ad.timer[0]) {
                clearTimeout(star_ad.timer[0]);
            };
            star_ad.timer[0] = setTimeout(function() {
                _message_box = LOOT.widget.showInfoMessage;
                _message_box.show(LOOT.constant.timeout_message);
            }, LOOT.constant.timeout);

            this.set_class_name(_tar);
            this.call_ajax(_tar.id);
            this.clicked = _tar;
        },
        set_class_name: function(tar) {
            if (tar.className == this.config.saved_class) {
                Dom.removeClass(tar, this.config.saved_class);
            } else {
                Dom.addClass(tar, this.config.saved_class);
            };
        },
        call_ajax: function(id) {
            var _servicePath = LOOT.constant.path.webservice + LOOT.constant.webservice.advert;
            var _methodName = "UpdateSavedAd";
            var _params = { savedAdvertId: id, externalUserId: EXTERNAL_USER_KEY };
            var _webServiceProxy = new Sys.Net.WebServiceProxy();
            _webServiceProxy.set_timeout(0);

            var _request = _webServiceProxy._invoke(_servicePath,   // the webservice to be called
                                                    _methodName,    // the method to call in the webservice
                                                    false,          // get (true) or post (false)
                                                    _params,        // parameteres expected by the method
                                                    this.handle_success,    // callback function for success
                                                    this.handle_failure);   // callback function for failure
        },
        handle_success: function(objJSON) {
            if (star_ad.timer[0]) {
                clearTimeout(star_ad.timer[0]);
            };

            LOOT.widget.showInfoMessage.hide();

            for (var i = 0; i < star_ad.counters.length; i++) {
                var _c = star_ad.counters[i];
                _c.innerHTML = '(' + objJSON + ')';
            };

        },
        handle_failure: function() {
            var _m;

            star_ad.set_class_name(star_ad.clicked);

            if (star_ad.timer[0]) {
                clearTimeout(star_ad.timer[0]);
            };
            if (LOOT.widget.showInfoMessage.hidden) {
                _m = 'Sorry, we encountered a problem, please try again.';
                LOOT.widget.showInfoMessage.show(_m);
            } else {
                _m = 'Sorry, we still appear to have a problem, please try again.';
                LOOT.widget.showInfoMessage.update(_m);
            };
            star_ad.timer[0] = setTimeout(function() {
                LOOT.widget.showInfoMessage.hide();
            }, LOOT.constant.timeout);
        }
    };
    Event.onAvailable(star_ad.config.trigger_id, star_ad.init, star_ad, true);

    var large_images = {
        config: {
            trigger_id: 'results',
            images_class_name: 'enlarge-image',
            magnify_class_name: 'enlarge',
            width: 400,
            height: 300,
            method: 'FitPad',
            split_item: '?',
            offsetfrommouse: [15, -75]
        },
        init: function() {
            var _images = new Array();

            this.docwidth = Dom.getDocumentWidth();
            this.docheight = Dom.getDocumentHeight();

            this.imagePanel = null;

            this.mousemoving = false;

            _images = Dom.getElementsByClassName(this.config.images_class_name);

            Event.addListener(_images, "mouseover", this.handle_mouseover, this, true);
            Event.addListener(_images, "mouseout", this.handle_mouseout, this, true);
            Event.addListener(document, "mousemove", this.handle_mousemove, this, true);
        },
        handle_mouseover: function(ev) {
            var _tar = Event.getTarget(ev),
                _string = '?t=tr/w:' + this.config.width + '/h:' + this.config.height + '/m:' + this.config.method,
                _img = Selector.query('img:not(.' + this.config.images_class_name + ')', _tar.parentNode, true),
                _src = _img.src.split(this.config.split_item)[0] + _string;

            this.mousemoving = true;

            var _html = '<div class="enlarge-image">';
            _html = _html + '<img src="' + _src + '" height="' + this.config.height + '" width="' + this.config.width + '" border="0" />';
            _html = _html + '</div>';

            if (typeof _imagePanel != "undefined") {
                _imagePanel.setBody(_html);
                _imagePanel.show();
            } else {
                try {
                    _imagePanel = new LOOT.panel.ModalRounded('',
                        {
                            id: 'lui_panel_overlay',
                            width: this.config.width + 50 + 'px',
                            underlay: 'none',
                            fixedcenter: false,
                            draggable: false,
                            close: false,
                            constraintoviewport: false,
                            modal: false,
                            zIndex: 10
                        }
                    );
                    _imagePanel.setBody(_html);
                    _imagePanel.setFooter('<div class="bl"></div><span></span><div class="br"></div>');
                    _imagePanel.show();
                } catch (ex) {
                    var _popup;
                    _popup = window.open("", "", 'width=900,height=500');
                    _popup.document.write(_html);
                };
            };
            this.imagePanel = _imagePanel;
        },
        handle_mouseout: function(ev) {
            this.mousemoving = false;
            this.imagePanel.setBody('');
            this.imagePanel.hide();
        },
        handle_mousemove: function(ev) {
            var _xcoord = this.config.offsetfrommouse[0];
            var _ycoord = this.config.offsetfrommouse[1];

            try {
                if (this.mousemoving) {
                    if (this.docwidth - Event.getPageX(ev) < 380) {
                        _xcoord = Event.getPageX(ev) - _xcoord - 400; // Move to the left side of the cursor
                    } else {
                        _xcoord += Event.getPageX(ev);
                    };

                    if (this.docheight - Event.getPageY(ev) < (this.config.height + 110)) {
                        _ycoord += Event.getPageY(ev) - Math.max(0, (110 + this.config.height + Event.getPageY(ev) - this.docheight - Dom.getDocumentScrollTop(document)));
                    } else {
                        _ycoord += Event.getPageY(ev);
                    };
                    // set x and y coords of the popup
                    this.imagePanel.moveTo(_xcoord, _ycoord);
                };
            } catch (ex) {
                // Do Nothing
            };
        }
    };
    Event.onAvailable(large_images.config.trigger_id, large_images.init, large_images, true);

    var category_count = {
        config: {
            trigger_id: 'category_suggestions',
            suggested_cat_class_name: 'suggested-categories',
            template_class_name: 'suggestion',
            toggle_class_name: 'toggle-hidden',
            toggled_class_name: 'toggled',
            showmore_class_name: 'show-more',
            hidden_class_name: 'hidden',
            more_text: 'show more',
            more_glyph: '▼', // &#9660;
            less_text: 'show fewer',
            less_glyph: '▲', // &#9650;
            row_threshold: 1,
            list_threshold: 5
        },
        init: function() {
            this.toggle_rows = false;
            this.show_link = Dom.get('show_all_categories');
            this.cat_rows = Selector.query('.' + this.config.suggested_cat_class_name),
            this.cat_lists = Selector.query('.' + this.config.suggested_cat_class_name + ' ul');
            // Hide the lists with more than the list_threshold of categories showing
            this.hide_lists();
            // Hide the rows with more than the row_threshold of categories showing
            if (this.cat_rows.length > this.config.row_threshold) { this.hide_rows(); };
        },
        hide_lists: function() {
            var _catArr = arguments[0] ? arguments : this.cat_lists,
                _self = category_count;

            for (i = 0; i < _catArr.length; i++) {
                var _parentUl = _catArr[i],
                    _cat_links = _catArr[i].getElementsByTagName('li');

                if (_cat_links.length > this.config.list_threshold) {
                    for (j = 5; j < _cat_links.length; j++) {
                        var _isSuggestion = Dom.hasClass(_cat_links[j], this.config.template_class_name),
                            _isToggle = Dom.hasClass(_cat_links[j], this.config.toggle_class_name);
                        // Only if the link is not a toggle link, or a suggested template link,
                        // add the 'hidden' classname.
                        if (!_isToggle && !_isSuggestion) {
                            Dom.addClass(_cat_links[j], this.config.hidden_class_name);
                        };
                    };
                    // Now check to see if the are any links hidden, potentially if the links were all template links,
                    // there would be no links hidden and the 'show more' toggle wouldn't be needed.
                    if (Selector.query('.' + this.config.hidden_class_name, _parentUl).length > 0) {
                        /*
                        If there is more than one UL in the array, then this is page init, and there should be no 'toggle links'
                        on the page. Therefore, create all new toggle links. If only one UL is in the array, this means the
                        toggle link has been clicked and doesn't need to be created. If so the else should reset the text
                        from 'show less' to 'show more'
                        */
                        if (_catArr.length > 1) {
                            var _more_text = document.createElement('u');
                            _more_text.appendChild(document.createTextNode(this.config.more_text));
                            var _more_glyph = document.createElement('small');
                            _more_glyph.appendChild(document.createTextNode(this.config.more_glyph));
                            var _more_link = document.createElement('a');
                            _more_link.href = 'javascript: void(0);';
                            _more_link.className = this.config.showmore_class_name;
                            _more_link.appendChild(_more_text);
                            _more_link.appendChild(_more_glyph);
                            var _more_link_li = document.createElement('li');
                            _more_link_li.className = this.config.toggle_class_name;
                            _more_link_li.appendChild(_more_link);

                            Event.addListener(_more_link, 'click', this.handle_click, _parentUl, true);

                            _parentUl.appendChild(_more_link_li);
                        } else {
                            Dom.getElementsByClassName(_self.config.toggled_class_name, 'a', _parentUl, function(el) {
                                // Remove the toggled class name.
                                Dom.removeClass(el, _self.config.toggled_class_name);
                                // reset the elements inside the more link
                                el.getElementsByTagName('u')[0].innerHTML = _self.config.more_text;
                                el.getElementsByTagName('small')[0].innerHTML = _self.config.more_glyph;
                            });
                        };
                    };
                };
            };
        },
        hide_rows: function(t) {
            try {
                // First interate through the rows, and hide the ones over the row_threshold
                for (i = this.config.row_threshold; i < this.cat_rows.length; i++) {
                    var _row = this.cat_rows[i];
                    Dom.addClass(_row, this.config.hidden_class_name);
                };
                // set the hidden rows toggle too 'true'
                this.toggle_rows = true;

                var _link_text = this.build_link_text();

                if (!t) {
                    var _show_link_span = this.show_link.getElementsByTagName('span')[0],
                        _show_link_glyph = document.createElement('small');
                    _show_link_glyph.appendChild(document.createTextNode(this.config.more_glyph));

                    this.show_link.getElementsByTagName('u')[0].innerHTML = _link_text;
                    this.show_link.replaceChild(_show_link_glyph, _show_link_span);

                    Event.addListener(this.show_link, 'click', this.handle_click);
                } else {
                    this.show_link.getElementsByTagName('u')[0].innerHTML = _link_text;
                    this.show_link.getElementsByTagName('small')[0].innerHTML = this.config.more_glyph;
                };
            } catch (ex) {
                // if there is a problem, set the toggle to false
                this.toggle_rows = false;
                // remove any event listeners
                Event.removeListener(this.show_link);
            };
        },
        handle_click: function(ev) {
            Event.stopEvent(ev);

            var _self = category_count,
                _tar = Event.getTarget(ev);

            if (_tar.parentNode.id) {
                if (_self.toggle_rows) {
                    _self.toggle_rows = false;
                    _self.show_link.getElementsByTagName('u')[0].innerHTML = _self.config.less_text + ' categories';
                    _self.show_link.getElementsByTagName('small')[0].innerHTML = _self.config.less_glyph;
                    Dom.removeClass(_self.cat_rows, 'hidden');
                } else {
                    _self.hide_rows(true);
                };
            } else {
                var _hidden_links = Dom.getElementsByClassName(_self.config.hidden_class_name, 'li', this, function(el, tar) {
                    if (!Dom.hasClass(tar.parentNode, _self.config.toggled_class_name)) {
                        Dom.addClass(tar.parentNode, _self.config.toggled_class_name);
                        if (tar.tagName.toLowerCase() == 'u') {
                            tar.innerHTML = _self.config.less_text;
                            Dom.getNextSibling(tar).innerHTML = _self.config.less_glyph;
                        } else {
                            tar.innerHTML = _self.config.less_glyph;
                            Dom.getPreviousSibling(tar).innerHTML = _self.config.less_text;
                        };
                    };
                    Dom.removeClass(el, _self.config.hidden_class_name);
                }, _tar);

                // If there are no hidden links, then they have already been un-hidden, so re-hide them!
                if (!_hidden_links.length) {
                    _self.hide_lists(this);
                };
            };
        },
        build_link_text: function() {
            var _query = Selector.query('div.hidden li:not(.toggle-hidden)'),
                _result_total = 0,
                _cat_total = _query.length;

            for (i = 0; i < _query.length; i++) {
                var _el = _query[i],
                    _sup = _el.getElementsByTagName('sup')[0],
                    _re = /([0-9]+)/i;
                _result_total = parseInt(_result_total) + parseInt(_sup.innerHTML.match(_re)[0]);
            };

            return 'We have found an extra \'' + _result_total + '\' results in \'' + _cat_total + '\' categories, show all';
        }
    }
    Event.onAvailable(category_count.config.trigger_id, category_count.init, category_count, true);


    var template_counts = {
        config: {
            trigger_id: 'category_suggestions',
            webservice_method: 'AdSearchCount'
        },
        init: function() {
            var _templates = Selector.query('#' + this.config.trigger_id + ' .suggestion a'),
                _url = LOOT.constant.path.webservice + LOOT.constant.webservice.advert + '/' + this.config.webservice_method,
                _callback = function(arg) {
                    return {
                        success: template_counts.success,
                        failure: template_counts.failure,
                        scope: template_counts,
                        timeout: 10000,
                        argument: arg
                    };
                };

            for (var i = 0; i < _templates.length; i++) {
                var _template = _templates[i],
                    _params = 'searchParameters=' + escape(_template.search),
                    _sup = Dom.getLastChild(_template);

                try {
                    _sup.innerHTML = '[ loading... ]';
                    Dom.addClass(_sup, 'loading');
                    Connect.asyncRequest('POST', _url, _callback(_sup), _params);
                } catch (ex) {
                    template_counts.failure({ argument: _sup });
                };
            };
        },
        success: function(o) {
            var _JSON = o.responseXML.getElementsByTagName('int')[0].childNodes[0].nodeValue,
                _sup = o.argument;

            _JSON = JSON.parse(_JSON);
            Dom.removeClass(_sup, 'loading');
            _sup.innerHTML = '(' + _JSON + ')';
        },
        failure: function(o) {
            var _sup = o.argument;

            Dom.replaceClass(_sup, 'loading', 'error');
            _sup.innerHTML = '[ error loading ]';
        }
    }
    Event.onAvailable(template_counts.config.trigger_id, template_counts.init, template_counts, true);

})();