/* Vulpine 2008 - Author Joe Fox */

/* Already in scope? let the interpreter skip execution again
 */
if (!ebayHandler) {
    /* constants
     */
    var kDEBUG      = false;

    var kASSET_UNSUPPORTED =    1;
    var kASSET_NOCONNECT   =    2;
    var kASSET_READY       =    4;
    var kASSET_MALFORMED   =    8;
    var kASSET_NOINIT      =   16;
    var kASSET_FOUND       =   32;
    var kASSET_NOTFOUND    =   64;

    var kCOMPAT_GECKO      =    1;
    var kCOMPAT_TRITON     =    2;
    var kCOMPAT_KHTML      =    3;

    var kHTTP_NOCACHE      = true;

    /* Widget Handler Class
     */
    var ebayHandler = function( aInstanceID ) {
        this.oContext = this;
        this.mCompat = kCOMPAT_GECKO;
        this.oScript;
        this.oConfig;
        this.mInstanceID;
        this.mInstanceNumber;
        
        /* Basic capability detection - gecko, triton and khtml/webkit
         */
        if (document.all && !self.opera) {
            this.mCompat = kCOMPAT_TRITON;
        } else if ( navigator.vendor == "KDE"
                 || ( document.childNodes 
                   && !document.all
                   && !navigator.taintEnabled
                   && !navigator.accentColorName ) ) {
            this.mCompat = kCOMPAT_KHTML;
        };
        
        /* Create or retrieve a unique widget reference. We'll use this
         * to make sure each widget recieves the correct data and events for
         * its remote file requests.
         */
        this.getInstance = function() {
            if (!this.mInstanceID) {
                /* Create a global scope widget handler collection
                 */
                if (!window['ebayhandlers']) {
                    window['ebayhandlers'] = { 
                        'instances': 0,
                        'references': {}
                    };
                };
                
                this.mInstanceNumber = ++ebayhandlers.instances;
                this.mInstanceID     = ( aInstanceID ? aInstanceID : 'instance_' + this.mInstanceNumber ) ;
                /* Add a reference to the new instance into the global widget collection.
                 */
                ebayhandlers[this.mInstanceID] = this;
                ebayhandlers.references[this.mInstanceID] = this;
            };
            return ebayhandlers[this.mInstanceID];        
        };
        
        /* prep and create a widget instance when the class is
         * instantiated
         */
        this.init();
        
        return this.getInstance();
    };

    /* Widget handler methods
     */
    ebayHandler.prototype = {
        /* (Re)initialise class members and event handlers
         */
        'init': function() {
            this.mState   = kASSET_NOINIT;
            this.mCounter = 0;
            this.mEvents  = {
                'onError':    null,
                'onSuccess':  null,
                'onStart':    null,
                'onFailure':  null,
                'onLoad':     null,
                'onComplete': function(asset) {
                    /* Basic asset onload event handler
                     * onFailure is called if the asset is malformed.
                     */
                    
                    if (asset) {
                        if (asset.status = kASSET_READY) {
                            this.fire(this.mEvents.onSuccess,[asset.response]);
                        } else if (asset.status = kASSET_MALFORMED) {
                            this.fire(this.mEvents.onFailure,[kASSET_MALFORMED]);
                        };
                    } else {
                        this.fire(this.mEvents.onFailure,[kASSET_NOTFOUND]);
                    };
                }
            };
        },
        /* Text node helper that wraps createElement. (below)
         */
        'createText': function(aText,aDomain) {
            return this.createElement(null,null,aText,aDomain);
        },
        /* Helper function that allows creation of DOM elements, attributes
         * and contents using one easy function call. Calls can be nested
         * to build whole DOM hierarchies.
         * Should also take account of several browser & tag caveats
         */
        'createElement': function(aElement, aAttributes, aContents, aDomain) {
            var type     = typeof aContents;
            var oElement = null;
            var oDoc     = aDomain || document;
            /* Contents is a string, and there's no tagname define, return
             * a text node
             */
            if (!aElement && type == 'string') {                  
                if (aContents.substring(1,0) == '<') {
                    var docFragment = this.createElement('div');
                    
                    docFragment.innerHTML = aContents;
                                           
                    return docFragment;
                } else {
                    return oDoc.createTextNode(aContents);
                };
            };
            /* Workaround for IE bug where dynamic input elements can't have 
             * their name attribute set
             */
            if ( aElement == 'input'
              && ( this.mCompat == kCOMPAT_TRITON )
              && aAttributes
              && aAttributes.name) {
                oElement = oDoc.createElement('<' + aElement + ' name="' + aAttributes.name + '" />');
            } else {
                oElement = oDoc.createElement(aElement);
            };
            /* Iterate through the attributes object and apply each one in
             * turn to the element object
             */
            if (aAttributes) {
                for (var i in aAttributes) {
                    if (aAttributes[i]) {
                        if (i == 'class') {
                            /* setAttribute('class'... doesn't work in all
                             * cases. Use className instead.
                             */
                            oElement.className = aAttributes[i];
                        } else if (i == 'style' && this.mCompat == kCOMPAT_TRITON ) {
                            /* IE requires a special way of setting tag
                             * level style attributes
                             */
                            oElement.style.cssText = aAttributes[i]; 
                        } else {
                            oElement.setAttribute(i,aAttributes[i]);
                        };
                    };
                };
            };
            /* If the contents parameter is an object, append it to the
             * element, otherwise assume it's text.
             */
            if (type == 'object') {
                oElement.appendChild(aContents);
            } else if (type == 'string') {
                if (aElement == 'style' && this.mCompat == kCOMPAT_TRITON ) {
                    /* IE has an unusual method for setting style
                     * tag contents. IE5.5 needs to wait for the style
                     * object to initialise first.
                     */
                    if (document.implementation) {
                        oElement.styleSheet.cssText = aContents;
                    } else {
                        setTimeout(function() {
                            oElement.styleSheet.cssText = aContents;
                            oElement = null;
                        },1);
                    };
                } else if (aElement == 'script' && this.mCompat == kCOMPAT_TRITON ) {
                    /* IE also has its own ideas about script content creation
                     */
                    oElement.text = aContents;
                } else {
                    oElement.appendChild(this.createElement(null,null,aContents,aDomain));
                };
            };
            return oElement;
        },
        /* Dynamically add style declarations to the document
         */
        'setStyle': function(aStyle, aOptions) {
            var aOptions       = aOptions || {};
            var oStyle         = null;          
            var id             = aOptions.id || this.mInstanceID;
            var oHead          = document.getElementsByTagName('head');
            
            /* Check if the style tag associated with our widget already
             * exists. If so, we can reuse it.
             */
            if (id) {
                oStyle = this.getTarget(id + '-style');
            };
            if (oStyle) {
                /* Clear existing styles if option is set
                 */
                if (aOptions.overwrite) {
                    oStyle.parentNode.removeChild(oStyle);
                } else {
                    return oStyle;
                };
            };
                   
            if (oStyle) {
                /* Append styles to existing stylesheet
                 */
                if (this.mCompat == kCOMPAT_TRITON ) {
                    oStyle.styleSheet.cssText += aStyle;
                } else {
                    oStyle.appendChild(this.createText(aStyle));
                };
            } else {
                /* Create a new stylesheet and add it to the document head
                 * if it exists or otherwise place it before the script tag.
                 * Note: webkit requires styles to be placed in the head
                 */
                oStyle = this.createElement('style', {
                    'type':  'text/css',
                    'media': 'all',
                    'id':    id + '-style'
                }, aStyle);
                
                if (oHead[0]) {
                    oHead[0].appendChild(oStyle); 
                };   
            };

            return oStyle;
        },
        /* Fetch an asset from a remote location - browser security means
         * we can't use ajax, so we'll use dynamic script tags with 
         * callbacks instead.
         */
        'fetch': function(aURI, aOptions) {
            var aOptions = aOptions || {};
            var oLoader  = this.getTarget(this.mInstanceID + '-loader') || null;
            var oHead    = document.getElementsByTagName('head');
            
            if (oLoader) {
                oLoader.parentNode.removeChild(oLoader);
            }
                            
            this.init();

            var oConfig = {
                'target':     aOptions.target     || null,
                'fetchuri':   aOptions.fetchuri   || aURI
            };
            
            this.mEvents.onSuccess  = aOptions.onSuccess  || null;
            this.mEvents.onFailure  = aOptions.onFailure  || null;
                         
            var oLoader = this.createElement('script', {
                'type':  'text/javascript',
                'src':   oConfig.fetchuri,
                'id':    this.mInstanceID + '-loader'
            });         
           
            if (oHead[0]) {
                oHead[0].appendChild(oLoader);
            };
                        
            this.fire(this.mEvents.onStart, [oConfig]);
        },
        
        /* Wrapper for getElementById that doesn't care if you specify an
         * id or a dom object.
         */
        'getTarget': function(target, domain) {
            var container = null;
            var doc       = domain || document;
            switch (typeof target) {
                case 'string':
                    container = doc.getElementById(target);
                break;
                case 'object':
                    if ( target.nodeType
                      && target.nodeType == 1) {
                        container = target;
                    };
                break;
            };
            return container;
        },
        /* Event handler which attempts to fire events in the widget's scope
         */
        'fire': function(aEventFunction,aProperties) {
            var type = typeof aEventFunction;

            switch (typeof aEventFunction) {
                case 'undefined':
                    return false;
                break;
                case 'function':
                    return aEventFunction.apply(this,aProperties);
                break;
                default:
                    if (window[aEventFunction]) {
                        return window[aEventFunction].apply(this,aProperties);
                    };
                break;
            };
        },
        /* Simple debug handler than can generate alerts or fire an error
         * handler callback
         */
        'debug': function(aException, aOptions) {
            var aOptions = aOptions || {};
            if (kDEBUG === true) {
                alert('Error in ' + aException);
            };
            if (this.mEvents.onError) {
                this.fire(this.mEvents.onError, [aException]);
            };
            return false;
        }
    };   

    ebayHandler.prototype.apiCall = function(aCall, aOptions) {
        var oConfig   = aOptions;
        var fetchOpts = {};
        var sURI      = 'http://open.api.ebay.com/Shopping?callname=' + (aCall || 'FindItemsAdvanced');
        
        oConfig.appid            = aOptions.appid     || 'bdnetwor-cb81-4a6a-b3e9-c568be131426';
        oConfig.version          = aOptions.version   || '561';
        oConfig.siteid           = aOptions.siteid    || '3';
        oConfig.responseencoding = aOptions.encoding  || 'JSON';
        
        if (!aOptions.callbackname) {
            oConfig.callbackname = 'ebayhandlers[\'' + this.mInstanceID + '\'].handleResponse';
        };

        for (var option in oConfig) {
            if (/^on(Success|Start|Failure)$/.test(option)) {
                fetchOpts[option] = oConfig[option];
                continue;
            };
            sURI += '&' + option + '=' + escape(oConfig[option]);
        };

        this.fetch(sURI,fetchOpts);
    };
    
    ebayHandler.prototype.handleResponse = function( response ) {
        if (response) {
            if (response.Ack && response.Ack == 'Success') {
                this.fire(this.mEvents.onSuccess,[response]);
            } else if (response.Ack && response.Ack != 'Success') {
                this.fire(this.mEvents.onFailure,[response.Errors[0].ErrorCode,response.Errors[0].LongMessage]);
            } else {
                this.fire(this.mEvents.onFailure,[kASSET_MALFORMED]);
            };
        } else {
            this.fire(this.mEvents.onFailure,[kASSET_NOTFOUND]);
        };     
    };

    ebayHandler.prototype.renderFitments = function(aObj, aType, aStuds, aStudsize, aCount) {
        var fitment;
        var oContainer = this.createElement('div'); 
        var labelText;
        var labelTextR;
        var count = aCount || 0;
        var oInput;

        for (var idx in aObj) {
            fitment = aObj[idx];
            labelText  = '';
            labelTextR = '';
 
            switch (finder) {
                case 'wheels':
                    if (fitment.rimwidth && fitment.rimwidth.value != '?') {
                        labelText = ' ' + fitment.rimwidth.value + 'J ' + fitment.tyrewidth.value + '/' + fitment.tyreaspect.value + ' R' + fitment.rimdiameter.value;
                    };
                    if (fitment.rimwidth_r) { 
                        if (fitment.rimwidth_r.value == '?') {
                            labelTextR = labelText;
                        } else {
                            labelTextR = ' ' + fitment.rimwidth_r.value + 'J ' + fitment.tyrewidth_r.value + '/' + fitment.tyreaspect_r.value + ' R' + fitment.rimdiameter_r.value;
                        };
                       
                    };
                    break;
                case 'rims':
                    if (fitment.rimwidth && fitment.rimwidth.value != '?') {
                        labelText = ' ' + fitment.rimwidth.value + 'J ' + aStuds.value + 'x' + aStudsize.value + ' R' + fitment.rimdiameter.value;
                    };
                    if (fitment.rimwidth_r) { 
                        if (fitment.rimwidth_r.value == '?') {
                            labelTextR = labelText;
                        } else {
                            labelTextR = ' ' + fitment.rimwidth_r.value + 'J ' + aStuds.value + 'x' + aStudsize.value + ' R' + fitment.rimdiameter_r.value;
                        };
                    };
                    break;
                case 'tyres':
                default:
                    if (fitment.tyrewidth && fitment.tyrewidth.value != '?') {
                        if (aType == 'upsteps' || aType == 'mm_upsteps') {
                            labelText = ' ' + fitment.tyrewidth.value + '/' + fitment.tyreaspect.value + ' ' + fitment.tyrediameter.value;
                        } else {
                            labelText = ' ' + fitment.tyrewidth.value + '/' + fitment.tyreaspect.value + ' ' + fitment.tyrediameter.value + ' ' + fitment.loadindex.value + ' ' + fitment.speedindex.value;
                        };
                    };
                    if (fitment.tyrewidth_r) { 
                        if (fitment.tyrewidth_r.value == '?') {
                            labelTextR = labelText;
                        } else {
                            if (aType == 'upsteps' || aType == 'mm_upsteps') {
                                labelTextR = ' ' + fitment.tyrewidth_r.value + '/' + fitment.tyreaspect_r.value + ' ' + fitment.tyrediameter_r.value;
                            } else {
                                labelTextR = ' ' + fitment.tyrewidth_r.value + '/' + fitment.tyreaspect_r.value + ' ' + fitment.tyrediameter_r.value + ' ' + fitment.loadindex_r.value + ' ' + fitment.speedindex_r.value;
                            };
                        };
                    };
                    break;
            };

            var oFitment = this.createElement('div', {
                'class': ((parseInt(idx) + count) % 2 == 1 ? 'odd': 'even')
            });

            var r2Query = getR2Query(fitment, aStuds, aStudsize);

            var clickEvent = 'if (this.checked) { setR2URI(this.value); }';

            if (aType == 'upsteps' || aType == 'mm_upsteps') {
                clickEvent = 'if (this.checked) { showDetails(document.getElementById(\'' + aType + '_container\')); setR2URI(this.value); }';
            };
            
            oInput  = null;
            
            if (labelText != '') {
                oInput = this.createElement('input', {
                    'type':    'radio',
                    'name':    'roptions',
                    'id':      'roptions',
                    'onclick': clickEvent,
                    'value':   r2Query.front
                });
                
                oFitment.appendChild(oInput);
            } else {
                oFitment.appendChild(this.createElement('div', {
                    'class': 'placeHolder' 
                }));
            };
           
            /*,
                'value': r2QueryString
            oFitment.appendChild(oInput);*/
            
            oFitment.appendChild(this.createElement('span', {}, labelText + (labelText != '' ? ' (front)': '')));
            
            if (labelTextR != '' && labelText != labelTextR) {
                oFitment.appendChild(this.createElement('input', {
                    'type':    'radio',
                    'name':    'roptions',//_' + (aType == 'shipped'? 'shipped':'custom'),
                    'id':      'roptions',
                    'onclick': clickEvent,
                    'value':   r2Query.rear
                }));
            } else {
                oFitment.appendChild(this.createElement('div', {
                    'class': 'placeHolder' 
                }));
            };
            
            oFitment.appendChild(this.createElement('span', {}, labelTextR + (labelTextR != '' ? ' (rear)': '')));
            
            if (idx == 0 && aType != 'upsteps') {
                if (aType == 'shipped' && oInput) {
                    oInput.setAttribute('checked','checked');
                    setR2URI(r2Query.front);
                };
                //oFitment.appendChild(this.createElement('span', {}, labelText + ' (front)'));
                //oFitment.appendChild(this.createElement('span', {}, labelTextR + ' (rear)'));
            } else {
                if (idx == 0 && aType != 'mm_upsteps') {
                    //oFitment.style.borderTop = '1px solid #888888';
                    
                    var subHeader = this.createElement('div', {
                        'class': ((parseInt(idx) + count) % 2 == 1 ? 'odd': 'even')
                    });
                    
                    subHeader.style.borderTop = '1px solid #888888';
                    subHeader.style.height = '46px';
                    
                    subHeader.appendChild(this.createElement('div', {
                        'class': 'subheader'
                    }, 'Upsteps'));
                    
                    subHeader.appendChild(this.createElement('div', {
                        'class': 'subbody'
                    }, 'Some of these fitments may require a wider wheel rim than that put on the car at the time of manufacture.'));
                    
                    oContainer.appendChild(subHeader);
                    count++;
                    
                    oFitment.className = ((parseInt(idx) + count) % 2 == 1 ? 'odd': 'even');                    
                };

                if (fitment.comment && fitment.comment != '') {
                    oFitment.appendChild(this.createElement('div', {
                        'class': 'extra_info'
                    },  this.createElement('p', {
                            'class': 'header'
                        }, fitment.comment.replace(/^[0-9\. ]*/,'')))
                    );
                };
            };        
            oContainer.appendChild(oFitment);
            if (this.mCompat == kCOMPAT_TRITON) {
                oContainer.innerHTML = oContainer.innerHTML; // initialise events under IE
            };
        };
        return oContainer;
    };

    ebayHandler.prototype.renderItemList = function( aItems, aID, aTitle, aURI ) {
        var oItem      = {};
        var oContainer = this.getTarget(aID);
        
        if (oContainer) {
            oContainer.innerHTML = '';
        };
                   
        var panelHeader = this.createElement('div', {
            'class': 'category_title'
        },  this.createElement('a', {
                'href': aURI,
                'title': aTitle
            }, aTitle)
        );
        
        var itemContainer = this.createElement('div',{
            'class': 'item-container'
        });
        
        panelHeader.appendChild(this.createElement('span', {
            'class': 'brand_amount'
        }, ' (' + aItems.TotalItems + ')'));
       
        itemContainer.appendChild(panelHeader);
                        
        for (var idx in aItems.SearchResult[0].ItemArray.Item) {
        
            oItem = aItems.SearchResult[0].ItemArray.Item[idx];
            
            if (!oItem.TimeLeft) {
                continue;
            };
            
            var item = this.createElement('div',{
                'class': 'item'
            });
            
            if (!oItem.GalleryURL) {
                oItem.GalleryURL = 'http://pics.ebaystatic.com/aw/pics/stockimage1.jpg';
            };
            
            var itemThumbnail = this.createElement('div', {
                'class': 'item_image_container'
            },  this.createElement('a', {
                    'href':   oItem.ViewItemURLForNaturalSearch,
                    'title':  'click to view item'
                },  this.createElement('img', {
                        'src':    oItem.GalleryURL,
                        'border': '0',
                        'class':  'item_image',
                        'alt':    oItem.Title
                    })
                )
            );

            var itemDetail = this.createElement('div', {
                'class': 'item-detail'
            });
            
            var titleLink = this.createElement('a', {
                'href':   oItem.ViewItemURLForNaturalSearch,
                'title':  'click to view item'
            },  oItem.Title + ' ');
                        
            var itemTitle = this.createElement('div', {
                'class': 'item_title'
            }, this.createElement('a', {
                'href':   oItem.ViewItemURLForNaturalSearch,
                'title':  'click to view item'
            },  oItem.Title));
            
            var price  = addCurrencySymbol(oItem.CurrentPrice.Value, oItem.CurrentPrice.CurrencyID);
            
            if (oItem.BuyItNowPrice && oItem.BuyItNowPrice != 0) {
                price += ' / ' + addCurrencySymbol(oItem.BuyItNowPrice.Value, oItem.CurrentPrice.CurrencyID);
            };
            
            var itemPrice = this.createElement('div', {
                'class': 'item_price'
            }, price + ' ');
            
            item.appendChild(itemThumbnail);
            item.appendChild(itemTitle);
            item.appendChild(itemPrice);
            
            if ((oItem.BuyItNowPrice && oItem.BuyItNowPrice != 0) || oItem.ListingType == 'FixedPriceItem' || oItem.ListingType == 'StoresFixedPrice') {
                var itemBIN = this.createElement('div', {
                    'class': 'item_bin_image_container'
                },  this.createElement('img', {
                        'src':    'http://pics.ebaystatic.com/aw/pics/bin_15x54.gif',
                        'border': '0',
                        'class':  'item_bin_image',
                        'alt':    'Buy It Now',
                        'title':  'Buy It Now',
                        'height': '15px',
                        'width':  '54px'
                    })
                );
                
                item.appendChild(itemBIN);
            };
            
            var itemTimeLeft = this.createElement('div', {
                'class': 'item_time_left'
            }, durationToStr(oItem.TimeLeft));
            
            item.appendChild(itemTimeLeft);
                        
            itemContainer.appendChild(item);                
        };
  
        itemContainer.appendChild(this.createElement('div',{
            'class': 'clear'
        }));
        
        oContainer.appendChild(itemContainer);
        
        delete oContainer;    
        
        return true;        
    };
    
};

var topWheels = document.getElementById('top_wheels');

if (topWheels) {
    var ebh = new ebayHandler();

    var fetchTopWheels = function() {
        ebh.apiCall('FindItemsAdvanced',{
            'CategoryID': 9888,
            'IncludeSelector': 'details',
            'MaxEntries': 4,
            'PreferredLocation': 'AvailableInCountryImplied',
            'ItemSort': 'BestMatchCategoryGroup',
            'ItemType': 'ExcludeStoreInventory',
            'SortOrder': 'Descending',
            'onSuccess': function(results) {
                if (results.SearchResult[0].ItemArray.Item) {
                    this.renderItemList(results, 'top_wheels', 'Car Wheels & Tyres', 'http://shop.ebay.co.uk/items/Wheels-with-Tyres__W0QQ_sacatZ9888QQ_dmptZUKQ5fCarPartsQ5fAccQ5fWheelsQ5ftyresQ5fRimsQ5fCarQ5fWheelsQ5fETQQ' )
                };
            },
            'onFailure': function(code, msg) {}
        });
    };
    fetchTopWheels();
};

var topTyres = document.getElementById('top_tyres');

if (topTyres) {
    var ebh2 = new ebayHandler();

    var fetchTopTyres = function() {
        ebh2.apiCall('FindItemsAdvanced',{
            'CategoryID': 9891,
            'IncludeSelector': 'details',
            'MaxEntries': 4,
            'PreferredLocation': 'AvailableInCountryImplied',
            'ItemSort': 'BestMatchCategoryGroup',
            'ItemType': 'ExcludeStoreInventory',
            'SortOrder': 'Descending',
            'onSuccess': function(results) {
                if (results.SearchResult[0].ItemArray.Item) {
                    this.renderItemList(results, 'top_tyres', 'Car Tyres', 'http://shop.ebay.co.uk/items/Tyres__W0QQ_sacatZ9891QQ_dmptZUKQ5fCarsQ5fTyresQ5fRLQQ' )
                };
            },
            'onFailure': function(code, msg) {}
        });
    };
    fetchTopTyres();
};

var topRims = document.getElementById('top_rims');

if (topRims) {
    var ebh3 = new ebayHandler();

    var fetchTopRims = function() {
        ebh3.apiCall('FindItemsAdvanced',{
            'CategoryID': 28648,
            'IncludeSelector': 'details',
            'MaxEntries': 4,
            'PreferredLocation': 'AvailableInCountryImplied',
            'ItemSort': 'BestMatchCategoryGroup',
            'ItemType': 'ExcludeStoreInventory',
            'SortOrder': 'Descending',
            'onSuccess': function(results) {
                if (results.SearchResult[0].ItemArray.Item) {
                    this.renderItemList(results, 'top_rims', 'Wheel Rims', 'http://shop.ebay.co.uk/items/Wheel-Rims__W0QQ_sacatZ28648QQ_dmptZUKQ5fCarPartsQ5fAccQ5fWheelsQ5ftyresQ5fTrimsQ5fCarQ5fRimsQ5fETQQ' )
                };
            },
            'onFailure': function(code, msg) {}
        });
    };
    fetchTopRims();
};

var ebh4 = new ebayHandler('vrm-lookup');
var vrmInput = document.getElementById('reg_search');

var r2URI   = '';
var r2Query = '';

if (!finder) {
    var finder = 'tyres';
};

var checkVRM = function() {
    if (vrmInput) {
        gotoStep('two');
        var uri;
        
        switch (finder) {
            case 'wheels':
                uri = 'fetchwheels';
                break;
            case 'rims':
                uri = 'fetchrims';
                break;
            case 'tyres':
            default:
                uri = 'fetchtyres';
                break;
        };
        ebh4.fetch('/ajax/' + uri + '?vrm=' + vrmInput.value + '&callback=vrm-lookup', {
            'onSuccess': function(obj) {
                if (obj.error) {
                    gotoStep('one');
                    showError('error_message', obj.error);
                    return false;
                };
            
                r2URI = obj.r2URI;
                
                var vehicleInfo    = this.getTarget('vehicle_info');
                var fitmentShipped = this.getTarget('fitment_options');
                var fitmentUpsteps = this.getTarget('fitment_upsteps');
                
                fitmentShipped.innerHTML = '';
                fitmentUpsteps.innerHTML = '';
                
                if (vehicleInfo) {
                    vehicleInfo.innerHTML = 'The registration <strong>' + vrmInput.value.replace('/[^0-9a-zA-Z ]/','') + '</strong> matched an ' + obj.make + ' ' + obj.model + ', ' + obj.doors + ', ' + obj.colour + ', ' + obj.transmission;
                };
                
                if (obj.drdinfo && obj.drdinfo.length > 0) {
                    var exactMatch;
                    if (obj.drdinfo.length == 1) {
                        exactMatch = obj.drdinfo;
                    } else {
                        exactMatch = [obj.drdinfo.shift()];
                        fitmentUpsteps.appendChild(this.renderFitments(obj.drdinfo, 'options', obj.studs, obj.studdiameter));
                    };
                    
                    fitmentShipped.appendChild(this.renderFitments(exactMatch, 'shipped', obj.studs, obj.studdiameter));
                    fitmentShipped.getElementsByTagName('input')[0].checked = 'checked';
                };
                
                if (obj.upsteps && obj.upsteps.length > 0) {
                
                    fitmentUpsteps.appendChild(this.renderFitments(obj.upsteps, 'upsteps', obj.studs, obj.studdiameter,obj.drdinfo.length));
                };
                
                gotoStep('three');
            },
            'onFailure': function(code, msg) {
                gotoStep('one');
                showError('error_message', 'There was a problem with your request. Please try again.');
            }
        });
    };
};

var makemodel    = new ebayHandler('makemodel-lookup');
var manufacturer = document.getElementById('makemodel_manufacturer');
var chassis      = document.getElementById('makemodel_model');
var model        = document.getElementById('makemodel_trim');

if (manufacturer) {
    var clearOptions = function(aObj) {
        var l = aObj.options.length;
        for (var o = aObj.options.length - 1; o >= 0; o--) {
            if (o == 0) {
                aObj.options[0].innerHTML = '-';
                
                continue;
            };
            aObj.remove(o);
        };       
    };

    var getMakeModel = function(aType, aID) {
        var uri       = '/makemodel/';
   
        switch (aType) {
            case 'fetch':
                uri += finder + '?model=' + model.options[model.selectedIndex].value;
            break;
            case 'chassis':
                clearOptions(chassis);
                clearOptions(model);

                uri += 'getchassis?selected=' + aID;
            break;
            case 'models':
                clearOptions(model);

                uri += 'getmodels?selected=' + aID;
            break;
            case 'manufacturers':
            default:
                clearOptions(chassis);
                clearOptions(model);

                uri += 'getmanufacturers?action=fetch'
            break;
        };
        
        
        makemodel.fetch( uri + '&callback=makemodel-lookup', {
            'onSuccess': function(obj) {
        
                if (obj.error) {
                    gotoStep('ten');
                    showError('mm_error_message', obj.error);
                    return false;
                };
            
                if (aType == 'fetch') {
                
                    r2URI = obj.r2URI;
        
                    var vehicleInfo    = this.getTarget('mm_vehicle_info');
                    var fitmentShipped = this.getTarget('mm_fitment_options');
                    var fitmentUpsteps = this.getTarget('mm_fitment_upsteps');
                    
                    fitmentShipped.innerHTML = '';
                    fitmentUpsteps.innerHTML = '';
                    
                    if (vehicleInfo) {
                        vehicleInfo.innerHTML = 'The following fitments matched your selection - <strong>' + manufacturer.options[manufacturer.selectedIndex].innerHTML + ' ' + model.options[model.selectedIndex].innerHTML + '</strong>';
                    };

                    if (obj.tyre) {
                        fitmentShipped.appendChild(this.renderFitments([obj.tyre], 'shipped', obj.studs, obj.studdiameter));
                        
                        fitmentShipped.getElementsByTagName('input')[0].checked = 'checked';
                    };

                    if (obj.upsteps && obj.upsteps.length > 0) {
                        fitmentUpsteps.appendChild(this.renderFitments(obj.upsteps, 'mm_upsteps', obj.studs, obj.studdiameter,0));
                   
                    };

                    gotoStep('twelve');
                        

                } else {
                    var vehicle;
                    
                    for (var idx in obj) {
                        vehicle = obj[idx];
                        switch (aType) {
                            
                            case 'chassis':
                                chassis.options[0].innerHTML =  'Select a model';
                                
                                chassis.appendChild(this.createElement('option', {
                                    'value': vehicle.ChassisID
                                },vehicle.ChassisTitle + ' ' + vehicle.UKYear));
    
                            break;
                            case 'models':
                                model.options[0].innerHTML =  'Select a trim';
                                
                                model.appendChild(this.createElement('option', {
                                    'value': vehicle.ModelID
                                },vehicle.ModelName));
                                
                                
                            break;
                            case 'manufacturers':
                            default:
                                manufacturer.options[0].innerHTML =  'Select a make';
                                manufacturer.appendChild(this.createElement('option', {
                                    'value': vehicle.ManufacturerID
                                },vehicle.ManufacturerName));
                                
                            break;
                        };                    
                    };
                    //document.body.appendChild(this.createText('<br/>'+vehicle.ManufacturerID + ':' + vehicle.ManufacturerName));
                };
            },
            'onFailure': function(code, msg) {
                gotoStep('ten');
                showError('error_message', 'There was a problem with your request. Please try again.');
                //alert('nej' + msg);
            }
        });
    
    };
    getMakeModel('manufacturers');
};


var setR2URI = function (aQuery) {
    r2Query = r2URI + aQuery;
};

var getR2Query = function(aObject, aStuds, aStudsize){
    var param;
    var sep        = ['',''];
    var query      = {'front':'','rear':''};
    
    for (var i in aObject) {
        param = aObject[i];
        if (param.value == '?' || i == 'comment') {
            continue;
        };
        if (i.substr(i.length-2) == '_r') {
            query.rear  += sep[1] + param.key + 'Z' + param.r2id;
            sep[1] = 'QQ';
        } else {
            query.front += sep[0] + param.key + 'Z' + param.r2id;
            sep[0] = 'QQ';
        };
    };
    if (aStuds) {
        query.front += sep[0] + aStuds.key    + 'Z' + aStuds.r2id;
        query.rear  += sep[1] + aStuds.key    + 'Z' + aStuds.r2id;
        query.front += 'QQ'   + aStudsize.key + 'Z' + aStudsize.r2id;
        query.rear  += 'QQ'   + aStudsize.key + 'Z' + aStudsize.r2id;
    };
    return query;
};

var durationToStr = function(duration) {
    var output     = '';
    var unit       = '';
    var matches    = duration.match(/P(?:([0-9]*)Y)?(?:([0-9]*)M)?(?:([0-9]*)D)?(?:T(?:([0-9]*)H)?(?:([0-9]*)M)?(?:([0-9\.]*)S)?)?/);
    var endingSoon = true;
    
    var oDuration = {
        'y':  matches[1],
        'mn': matches[2],
        'd':  matches[3],
        'h':  matches[4],
        'm':  matches[5],
        's':  matches[6]
    };
    
    for ( var idx in oDuration ) {
        if (!oDuration[idx] || oDuration[idx] < 1) {
            continue;
        };
        output += ( output != '' ? ' ' : '' ) + unit;
        
        if (idx == 's') {
            oDuration[idx] = Math.floor(oDuration[idx]);
        } else if (idx != 'm') {
            endingSoon = false;
        };
        unit = oDuration[idx] + idx;
    };
    output += ( output != '' ? ' and ' : '' ) + unit;

    if (endingSoon && (!oDuration['m'] || oDuration['m'] < 10)) {
        return '<span class="ending">' + output + '</span>';
    } else {
        return output;
    };
};

var addCurrencySymbol = function(price, code) {
    price = price.toFixed(2);
    var symbol = price + ' ' + code;
    
    switch (code) {
        case 'GBP':
            symbol = '£' + price;
        break;
        case 'EUR':
            symbol = '€' + price;
        break;
        case 'USD':
            symbol = '$' + price;
        break;
    };
    return symbol;
};

gotoStep('one');