Form.Element.Serializers.selectOne = function(element) {
    var value = '', opt, index = element.selectedIndex;
    if (index >= 0) {
        opt = element.options[index];
        value = opt.value;
    }
    return [element.name, value];
}

Form.Element.Serializers.selectMany = function(element) {
    var value = [];
    for (var i = 0; i < element.length; i++) {
        var opt = element.options[i];
        if (opt.selected)
            value.push(opt.value || opt.text);
    }
    return [element.name, value];
}

Object.extend(Event, {
    _domReady : function() {
        if (arguments.callee.done) return;
        arguments.callee.done = true;

        if (this._timer)  clearInterval(this._timer);

        this._readyCallbacks.each(function(f) { f() });
        this._readyCallbacks = null;
        this._loaded = true;
    },

    onDOMReady : function(f) {
        if (this._loaded) {
            f();
            return ;
        }
        if (!this._readyCallbacks) {
            var domReady = this._domReady.bind(this);

            if (document.addEventListener)
                document.addEventListener("DOMContentLoaded", domReady, false);

            /*@cc_on @*/
            /*@if (@_win32)
              document.onload = function() { domReady(); }
              //document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
              //document.getElementById("__ie_onload").onreadystatechange = function() {
              //if (this.readyState == "complete") domReady();
              //};
              /*@end @*/

            if (/WebKit/i.test(navigator.userAgent)) {
                this._timer = setInterval(function() {
                    if (/loaded|complete/.test(document.readyState)) domReady();
                }, 10);
            }

            Event.observe(window, 'load', domReady);
            Event._readyCallbacks =  [];
        }
        Event._readyCallbacks.push(f);
    }
});

Element.addMethods(
{
    update: function(element, html) {
        html = typeof html == 'undefined' ? '' : html.toString();
        $(element).innerHTML = html.stripScripts();
        setTimeout(function() {
            html.evalScripts();
            try {
                Mxmfo.history.ajaxify(element);
            } catch (e) {
            }
        }, 10);
        return element;
    },

    replace: function(element, html) {
        element = $(element);
        html = typeof html == 'undefined' ? '' : html.toString();
        if (element.outerHTML) {
            element.outerHTML = html.stripScripts();
        } else {
            var range = element.ownerDocument.createRange();
            range.selectNodeContents(element);
            element.parentNode.replaceChild(
                                            range.createContextualFragment(html.stripScripts()), element);
        }
        setTimeout(function() {
            html.evalScripts();
            try {
                Mxmfo.history.ajaxify(element);
            } catch (e) {
            }
        }, 10);

        return element;
    }
});

function MyHistory()
{
    this.defaultLocation = null;
    this.initLoading();

    /* history support */
    dhtmlHistory.initialize();
    dhtmlHistory.addListener(this.historyChange.bind(this));

    // determine what our initial location is
    // by retrieving it from the browser's
    // location after the hash
    currentLocation = dhtmlHistory.getCurrentLocation();
    if (currentLocation == '') {
        var url = String(document.location);
        this.defaultLocation = this.getHashFromUrl(url);
        historyStorage.put(this.defaultLocation, url + '::');
    }

    // ajax
    Ajax.Responders.register({
        onLoading: function() {
            Ajax.loading_cnt++;
            Ajax.loading_div.show();
        }
    });
    this.ajaxify(document);
}

MyHistory.prototype.initLoading = function()
{
    Ajax.clicked_obj = null;
    Ajax.loading_cnt = 0;
    Ajax.loading_div = $('loading');
    Event.observe(document, 'scroll', this.scrollLoading.bindAsEventListener(this));
}

MyHistory.prototype.scrollLoading = function(event)
{
    res = document.documentElement.scrollTop || document.body.scrollTop;
    Ajax.loading_div.setStyle({top: res + 'px'});
}

MyHistory.prototype.ajaxCallback = function(XHR, eJSON)
{
    try {
        eval(eJSON);
    } catch (e) {
        //alert(e.message);
    }
    if (Ajax.clicked_obj && Ajax.clicked_obj.submited) {
        Ajax.clicked_obj.submited = false;
    }
    if (Ajax.loading_cnt > 0) {
        Ajax.loading_cnt--;
    }
    if (Ajax.loading_cnt == 0) {
        Ajax.loading_div.hide();
    }
}

MyHistory.prototype.ajaxifyLink = function(node)
{
    node = $(node);
    if (typeof(node.alreadyObserved) == 'undefined') {
        node.alreadyObserved = true;
        node.listner = this.click.bindAsEventListener(this, node);
        node.observe('click',
                     node.listner);
    }
}

MyHistory.prototype.deAjaxifyLink = function(node)
{
    link.stopObserving('click', link.listner);
}

MyHistory.prototype.ajaxify = function(root)
{
    root = $(root);

    /* parse links */
    current = root.getElementsByTagName('a');
    curLen = current.length;
    for (j = 0; j < curLen; j++) {
        if (current[j].name != 'ajax') {
            continue;
        }
        this.ajaxifyLink(current[j]);
    }

    /* parse forms */
    current = root.getElementsByTagName('input');
    curLen = current.length;
    for (j = 0; j < curLen; j++) {
        if (current[j].name != 'ajax' || !current[j].form) {
            continue;
        }

        this.addAjaxForm(current[j].form);
    }

    if (Ajax.loading_cnt == 0) {
        Ajax.loading_div.hide();
    }
}

MyHistory.prototype.addAjaxForm = function(form)
{
    form = $(form);
    form.submitForm = this.submitForm.bind(this, form);
    form.observe('submit', this.checkFormSubmit.bindAsEventListener(this, form));
    if (!form.getInputs('submit').length) {
        inputs = form.getInputs();
        for (i = 0; i < inputs.length; i++) {
            if (inputs[i].type != 'password' && inputs[i].type != 'text') {
                continue;
            }
            inputs[i].observe('keyup',
                              this.checkFormSubmit.bindAsEventListener(this, form));
        }
    }
}

MyHistory.prototype.click = function(e, node)
{
    try {
        Lightbox.hideBox();
    } catch (e) {
    }
    Ajax.clicked_obj = $(node);
    this.request(Ajax.clicked_obj.href, Ajax.clicked_obj.hasClassName('no_history'));
    Event.stop(e);
}

MyHistory.prototype.request = function(url, noHistory)
{
    var pars = '';
    if (!noHistory) {
        dhtmlHistory.add(this.getHashFromUrl(url), url + '::' + pars);
    }

    var myAjax = new Ajax.Request(url,
        {
            method: 'get',
            parameters: pars,
            onComplete: this.ajaxCallback.bind(this)
        });
}

MyHistory.prototype.submitForm = function(form)
{
    form = $(form);
    form.submited = true;
    Ajax.clicked_obj = form;
    form.request({
        onComplete: this.ajaxCallback.bind(this)
    });
}

MyHistory.prototype.checkFormSubmit = function(e, form)
{
    Event.stop(e);
    form = $(form);

    if ((!e.keyCode || e.keyCode == Event.KEY_RETURN) && !form.submited) {
        this.submitForm(form);
    }
}

MyHistory.prototype.displayLocation = function(historyData)
{
    if (!historyData) {
        if (!this.defaultLocation) {
            var hash = String(document.location).split('#')[1];
            if (!hash || !hash.length) {
                return ;
            }
            historyData = historyStorage.get(hash);
        } else {
            historyData = historyStorage.get(this.defaultLocation);
        }
    }

    if (historyData) {
        var a = historyData.split('::');
        var myAjax = new Ajax.Request(a[0],
            {
                method: 'get',
                parameters: a[1],
                onComplete: this.ajaxCallback.bind(this)
            }
                                      );
    }
}

MyHistory.prototype.getHashFromUrl = function(url)
{
    return (MD5Hash.hex_md5(url));
}

MyHistory.prototype.historyChange = function(newLocation, historyData)
{
    if (newLocation.length != 32) {
        return;
    }
    this.displayLocation(historyData);
}

var Mxmfo = {
    history: null,
    eval_data: null,

    init: function() {
        Mxmfo.history = new MyHistory();
        Mxmfo.initExternals();
        if (Mxmfo.eval_data) {
            try {
                eval(Mxmfo.eval_data);
            } catch (e) {
            }
        }
    },

    initExternals: function() {
        links = document.getElementsByTagName('a');
        for (i = 0; i < links.length; i++) {
            if (links[i].rel) {
                if (links[i].rel == 'external'
                    || links[i].rel.match(new RegExp("(^|\\s)external(\\s|$)"))) {
                    links[i].target = '_blank';
                }
            }
        }
    },

    displayMenu: function(menu) {
        menu = $(menu);
        if (!menu) {
            return ;
        }
        for (i = 1; i <= 10; i++) {
            smenu = $('smenu' + i);
            if (smenu) {
                smenu.hide();
            }
        }
        if (!menu.visible()) {
            menu.show();
        }
    },

    updateSubCategories: function(selector, k, sub_selector, url) {
        selector = $(selector);
        sub_selector = $(sub_selector);
        id = selector.getValue()[1];
        if (id.length) {
            url = url.replace('999999', id);
        } else {
            option = sub_selector.down('option').next('option');
            while (option) {
                to_del = option;
                option = option.next('option');
                to_del.remove();
            }
        }
        k = $(k).getValue();
        if (k.length) {
            url += '?k=' + escape(k);
        }
        Mxmfo.history.request(url, true);
    },

    enableLightboxes: function(loginurl) {
        nodes = new Array();

        /* account tab link */
        node = $('tab:account');
        if (node) {
            nodes.push(node.down('a'));
        }

        node = $('nav:sponsoring');
        if (node) {
            nodes.push(node);
        }

        node = $('more:sponsoring');
        if (node) {
            nodes.push(node);
        }

        node = $('nav:maximail');
        if (node) {
            nodes.push(node);
        }

        node = $('nav:survey');
        if (node) {
            nodes.push(node);
        }

        node = $('more:survey');
        if (node) {
            nodes.push(node);
        }

        node = $('more:maximail');
        if (node) {
            nodes.push(node);
        }

        node = $('nav:profil');
        if (node) {
            nodes.push(node);
        }

        node = $('more:profil');
        if (node) {
            nodes.push(node);
        }

        node = $('milespurchase:selfpurchase');
        if (node) {
            nodes.push(node);
        }

        node = $('milespurchase:memberpurchase');
        if (node) {
            nodes.push(node);
        }

        /* add to cart button */
        node = $('add_to_cart');
        if (node) {
            nodes.push(node);
        }

        /* ask search */
        node = $('ask_search');
        if (node && !node.hasClassName('disable_lightbox')) {
            nodes.push(node);
        }

        /* ipoll */
        node = $('nav:ipoll');
        if (node) {
            nodes.push(node);
        }
        node = $('send');
        if (node) {
            nodes.push(node);
        }

        /* enable lightbox links */
        base_url = loginurl + (loginurl.include('?') ? '&' : '?') + 'ref=';
        for (i = 0; i < nodes.length; i++) {
            if (nodes[i].href) {
                /* link */
                if (nodes[i].href.indexOf('?ref=') == -1) {
                    nodes[i].href =  base_url + escape(nodes[i].href.replace(/https?:\/\/[^\/]+/, ''));
                    Mxmfo.history.ajaxifyLink(nodes[i]);
                }
            } else {
                /* form */
                if (nodes[i].action) {
                    ref = nodes[i].action;
                } else {
                    ref = new String(document.location);
                }
                nodes[i].onsubmit = function() {
                    Mxmfo.history.request(base_url + escape(ref.replace(/https?:\/\/[^\/]+/, '')));
                    return false;
                }
            }
        }

        node = $$('a.amazon_add');
        if (node) {
            for (i = 0; i < node.length; i++) {
                node[i].href = base_url + escape(document.location.href);
                Mxmfo.history.ajaxifyLink(node[i]);
                nodes.push(node[i]);
            }
        }

        node = $$('a.wishlist');
        if (node) {
            for (i = 0; i < node.length; i++) {
                node[i].href = base_url + escape(document.location.href);
                Mxmfo.history.ajaxifyLink(node[i]);
                nodes.push(node[i]);
            }
        }

        node = $$('a.favorites');
        if (node) {
            for (i = 0; i < node.length; i++) {
                node[i].href = base_url + escape(document.location.href);
                Mxmfo.history.ajaxifyLink(node[i]);
                nodes.push(node[i]);
            }
        }
    },

    disableLightboxes: function(accounturl) {
        tabaccount = $('tab:account');
        if (tabaccount) {
            link = tabaccount.down('a');
            link.href = accounturl;
            Mxmfo.history.deAjaxifyLink(link);
        }
    },

    updateChildData: function(select) {
        select = $(select);
        val = select.getValue()[1];
        if (val == '5+') {
            val = '5';
        }
        for (i = 1; i < 6; i++) {
            if (i <= val) {
                $('poll:child:' + i).show();
            } else {
                $('poll:child:' + i).hide();
            }
        }
    },

    updateIntervalSelectors: function(min_select, max_select) {
        min = new Number($(min_select).getValue()[1]);
        opt = $(max_select).down('option');
        selected = false;
        while (opt) {
            if (opt.value.length) {
                if (new Number(opt.value) > min) {
                    opt.disabled = false;
                    if (selected) {
                        selected = false;
                        opt.selected = true;
                    }
                } else {
                    opt.disabled = true;
                    if (opt.selected) {
                        selected = true;
                    }
                }
            } else {
                if (selected) {
                    opt.selected = true;
                }
            }
            opt = opt.next('option');
        }
    },

    checkUkPostCode: function(cp, url) {
        cp = $(cp);
        country = $('country');
        if (!country) {
            country = $('pays');
        }
        if (cp.value.length && country.selectedIndex) {
            Mxmfo.history.request(url + '?cp=' + escape(cp.value) + '&country=' + escape(country.options[country.selectedIndex].value),
                                  true);
        }
    },

    checkUkPostKey: function() {
        if (!(country_selector = $('country')) && !(country_selector = $('pays'))) {
            return;
        }

        if (!(fulladdr_selector = $('fulladdr'))) {
            return;
        }

        if (!(cp_input = $('cp'))) {
            return;
        }

        if (!cp_input.value.length) {
            return;
        }

        if (   country_selector.options[country_selector.selectedIndex].value != 'uk'
            || fulladdr_selector.options[fulladdr_selector.selectedIndex].value == cp_input.value) {
            // user said its address is not on the list
            // showing him empty fields to input its actual address
            $('addr1').value = '';
            $('addr2').value = '';
            $('localite').value = '';
            $('ville').value = '';
            $('region').value = '';

            $('p:addr1').show();
            $('p:addr2').show();
            $('p:localite').show();
            $('p:ville').show();
            $('p:region').show();
        } else {
            // user picked one of the address in the list
            // need to be sure all adress fields are invisible
            $('addr1').value = '';
            $('addr2').value = '';
            $('localite').value = '';
            $('ville').value = '';
            $('region').value = '';

            $('p:addr1').hide();
            $('p:addr2').hide();
            $('p:localite').hide();
            $('p:ville').hide();
            $('p:region').hide();

            // clear eventual error message
            if (addr_error = $('addr_error')) {
                addr_error.hide();
            }
        }
    },

    popUp2: function(theURL, winName, features) {
        window.open(theURL, winName, features);
    }
}

Event.onDOMReady(function() {
    Mxmfo.init();
});

