var fanlebrity_ajaxdrop = function(){ return this;};

fanlebrity_ajaxdrop.prototype = {

    initialize: function() { },

    _adBox: null,
    config: null,
    tempOnMouseUpHandler: null,
    ajaxKey: '',
    defaultUrls: {
        celebs: 'index.php?d=celeblist&search=%value%',
        celebsTrade: 'index.php?d=list&e=Go&search=%value%&table=celebs',
        players: 'index.php?d=list&e=Go&search=%value%&table=players',
        celebInfoPop: 'index.php?d=celebMouseOver&id_celeb=%value%'
    },
    hideTimeout: null,

    addTarget: function(t, url, opts) {
        var hid, img, f, dir = 0, getValue, menuClass = 'menu1';
        // dir 0 = down, 1 = up

        t = $(t);
        if (!opts) opts = {};

        if (!!opts.hid) hid = opts.hid;
        if (!!opts.img) img = opts.img;
        if (!!opts.f) f = opts.f;
        if (!!opts.dir) dir = opts.dir;
        if (!!opts.val) {
            getValue = function() { return opts.val; };
        } else {
            getValue = function() { return t.value; };
        }
        if (!!opts.altClass) menuClass = opts.altClass;
        if (!!opts.addClass) menuClass += ' ' + opts.addClass;

        if (!f) {
            f = function(e) {
                if (t.tagName == "input") t.value = e.name;
                if (!!hid) hid.value = e.id;
                if (!!img) img.src = e.img;
            };
        }

        t.observe('popup:click', function(e) { f(e.memo.res, e.memo.obj); });

        if (!!this.defaultUrls[url])
            url = this.defaultUrls[url];

        var config = { target: t, getValue: getValue, evt: f, url: url, dir: dir, menuClass: menuClass };

        var _this = this;
        var _evtShow = function(e) { _this.ad_evtShow(e, config); };

        if (t.tagName.toLowerCase() == "input") {
            var _evtHide = function(e) { _this.ad_evtHide(e); };
            var _evtUpdate = function(e) { _this.ad_evtUpdate(e, config); };

            t.onfocus = $(_evtShow).bindAsEventListener(this);
            t.onblur = $(_evtHide).bindAsEventListener(this);
            t.onkeyup = $(_evtUpdate).bindAsEventListener(this);
        } else {
            var _evtHide = function(e) { _this.ad_evtHideDelay(e); };

            t.onmouseover = $(_evtShow).bindAsEventListener(this);
            t.onmouseout = $(_evtHide).bindAsEventListener(this);
        }


    },

    ad_evtShow: function(e, config) {
        this.clearHide();
        if (!!this.tempOnMouseUpHandler) {
            Event.stopObserving(window.document, 'mouseup', this.tempOnMouseUpHandler);
            this.tempOnMouseUpHandler = null;
        }

        var t = Event.element(e);
        this.config = config;
        if (!!t) this.showMenu(config);
    },

    ad_evtHide: function(e) {
        this.clearHide();
        var txt = Event.element(e);
        if ((!!txt) && (txt == this.config.target))
            this.hideMenu();
    },

    ad_evtHideDelay: function(e) {
        dOut('ad_evtHideDelay');

        var txt = Event.element(e);
        if ((!!txt) && (this.isOrContains(this.config.target, txt))) {
            this.clearHide();
            this.hideTimeout = window.setTimeout(this.doHideMenu.bindAsEventListener(this), 1000);
            Event.observe(txt, 'mousemove', this.clearHide);
        } else {
            dOut(txt);
        }
    },

    ad_evtUpdate: function(e, config) {
        this.clearHide();

        if (this.config != config) {
            var t = Event.element(e);
            this.config = config;
            if (!!t) this.showMenu(config);
        }

        this.loadMenu(config.getValue(), config.url);
    },

    clearHide: function() {
        if (!this.config) return;
        dOut('clearHide');
        Event.stopObserving(this.config.target, 'mousemove', this.clearHide);
        Event.stopObserving(this.getMenu(), 'mousemove', this.clearHide);
        if (!!this.hideTimeout) {
            window.clearTimeout(this.hideTimeout);
            this.hideTimeout = null;
        }
    },

    getMenu: function() {
        if (!!this._adBox) {
            return this._adBox;
        } else {
            var outdiv = new Element('div', { id: 'adMenu', 'class': 'menu1' })
                .setStyle({
                    position: 'absolute',
                    left: '-3000px',
                    top: '-3000px',
                    width: '300px',
                    border: 'solid 1px black',
                    overflow: 'auto'
                }
            );

            var indiv = new Element('div').setStyle({ overflow: 'visible' });

            outdiv.appendChild(indiv);
            window.document.body.appendChild(outdiv);

            outdiv.onclick = this.menu_OnClick.bindAsEventListener(this);
            outdiv.onmousemove = this.menu_OnMouseOver.bindAsEventListener(this);
            outdiv.onmouseout = this.menu_OnMouseOut.bindAsEventListener(this);


            this._adBox = outdiv;
        }

        return this._adBox;
    },

    loadMenu: function(txt, url) {
        var c = null;
        var m = this.getMenu();

        var ad = this;
        this.ajaxKey = (new Date()).getTime();
        var key = this.ajaxKey;
        var url1 = url.replace(/%value%/g, encodeURIComponent(txt));

        var i = url1.indexOf('?');
        var url2 = url1.substring(0, i);
        var params = url1.substring(i + 1);

        this.setContent('Loading...');

        _ajaxr.req({
            url: url2,
            params: params,
            onSuccess: function(r) { ad.onReceiveContent(r, key, url1); },
            stackKey: 'dropdownB',
            override: 'dropdownB',
            resume: true,
            method: 'get',
            useCache: true,
            id: m.firstDescendant(),
            destChild: true,
            sourceChild: false,
            runActions: false
        });

        return m;
    },

    onReceiveContent: function(r, key, url) {
        if (this.ajaxKey != key) return;

        r.updateContent();
        this.fitMenu();
    },

    setContent: function(c) {
        var m = this.getMenu();

        m.className = this.config.menuClass;
        m.firstDescendant().update(c);
        this.fitMenu();
    },

    showMenu: function(config) {
        var m = this.loadMenu(config.getValue(), config.url);
        var t = config.target;
        var pos = Element.cumulativeOffset(t);
        var h = t.offsetHeight;
        var w = t.offsetWidth;
        var mh = m.offsetHeight;
        var mw = m.offsetHeight;


        switch (config.dir) {
            case 0:
                Element.setStyle(m, { position: 'absolute', top: pos.top + h + 'px', left: pos.left + 'px', bottom: null });
                break;
            case 1:
                Element.setStyle(m, { position: 'fixed', bottom: '25px', left: pos.left + 'px', top: null });
                break;
        }
    },

    hideMenu: function() {
        var ad = this;

        this.tempOnMouseUpHandler = function() {
            ad.doHideMenu();
            Event.stopObserving(window.document, 'mouseup', ad.tempOnMouseUpHandler);
            ad.tempOnMouseUpHandler = null;
        }

        Event.observe(window.document, 'mouseup', this.tempOnMouseUpHandler);
    },

    doHideMenu: function() {
        var m = this.getMenu();
        Element.setStyle(m, { top: '-3000px', left: '-3000px' });
    },


    fitMenu: function() {
        var MAX_HEIGHT = 300;
        //this._adBox.setStyle({ height: '0px' });
        this._adBox.setStyle({ width: '100px' });

        var sh = this._adBox.scrollHeight;
        var sw = this._adBox.scrollWidth;

        //alert(sh);

        if (sh > MAX_HEIGHT + 10) {
            this._adBox.setStyle({ height: MAX_HEIGHT + 'px', overflow: 'auto' });
            sw += 16;
        } else
            this._adBox.setStyle({ height: null, overflow: 'hidden' });

        this._adBox.setStyle({ width: sw + 'px' });
    },

    menu_OnClick: function(evt) {
        var o = Event.element(evt);
        var obj = this.getMenuItem(o);
        var res = this.getMenuJSON(obj);

        this.config.target.fire('popup:click', { res: res, obj: obj });
    },

    menu_OnMouseOver: function(evt) {
        if (this.config.target.tagName.toLowerCase() == "input") return;
        this.clearHide();
    },

    menu_OnMouseOut: function(evt) {
        if (this.config.target.tagName.toLowerCase() == "input") return;
        this.clearHide();
        this.hideTimeout = window.setTimeout(this.doHideMenu.bindAsEventListener(this), 1000);
        Event.observe(this.getMenu(), 'mousemove', this.clearHide);
    },

    getMenuItem: function(o) {
        var hidJSON = null;

        while ((o != this._adBox) && (!hidJSON)) {
            hidJSON = Element.firstDescendant(o);
            if ((!!hidJSON) && (hidJSON.name == "hidJSON"))
                hidJSON = Element.firstDescendant(o);
            else {
                o = o.up();
                hidJSON = null;
            }
        }

        if (!!hidJSON)
            return o;
        else
            return null;
    },

    getMenuJSON: function(o) {
        if (!o) return null;

        var hidJSON = null;

        hidJSON = Element.firstDescendant(o);

        if (!!hidJSON)
            return eval(" ___0 = " + hidJSON.value);
        else
            return null;
    },

    isOrContains: function(obj1, obj2) {
        if (obj1 == obj2) return true;

        element = $(obj2), ancestor = $(obj1);
        while (element = element.parentNode)
            if (element == ancestor) return true;
        return false;
    }

};


function dOut(d) {
    if (!!$('txtDebugLog'))
        $('txtDebugLog').value = d + '\n' + $('txtDebugLog').value;
}


var _ajdd = new fanlebrity_ajaxdrop();