var map = new Object();
/* stub so wBids runs without debug console */
window.dprint = function(str) { }

function wBids(tick)
{
    var self = this;

    self.now = false;
    self.items = new Array();
    if(typeof ping_url == 'string')
        self.request = new Request(ping_url);
    else
        self.request = new Request('cmd/ping.php');
    self.request.setPacker('needPing');
    self.info_request = new Request('cmd/iteminfo.php');
    self.info_request.setPacker('needInfo');
    self.bid_request = new Request('cmd/bid.php');
    self.bid_request.setPacker('needBid');
    self.agent_request = new Request('cmd/agent.php');
    self.agent_request.setPacker('agentRequest');
    self.refresh_request = false;
    self.itemFunc = null;
    self.tick = tick;
    self.interval = false;
    self.last_request = 0;
    self.last_agent_request = 0;
    self.clock = false;
    self.single = false;
    self.version = false;
    self.use_refresh = false;
    self.ping_interval = 0;
    self.agent_interval = 0;
    self.time_shift = 0;    // current shift

    self.activity = function()
    {
        self.last_active = (self.now.getTime() / 1000) + self.time_shift;
    }

    self.singleItem = function(id)
    {
        self.single = id;
        if(typeof self.items[id] != 'undefined') {
            self.items[id].setSingle(true);
        }
    }

    /* adds a new item to the run() loop */
    self.addItem = function(id)
    {
        self.items[id] = new BidItem(id);
        self.request.addObject(self.items[id]);
        self.info_request.addObject(self.items[id]);
        return self.items[id];
    }

    self.useRefresh = function()
    {
        self.use_refresh = true;
    }

    /* reset wbids completely */
    self.refresh = function()
    {
        if(self.use_refresh) {
            if(!self.refresh_request) {
                self.refresh_request = new Request('refresh.php');
                self.refresh_request.setCallback(self.refreshCallback);
            }
            self.refresh_request.run();
        } else {
            // use old full refresh
            window.location.reload();
        }
    }

    self.refreshCallback = function(data)
    {
        self.request.clearObjects();
        for(var i in self.items) {
            delete self.items[i];
        }
        document.getElementById('wbids_products').innerHTML = data;
        var ids = eval(document.getElementById('wbids_products_id').innerHTML);
        for(var i in ids) {self.addItem(ids[i]);}
        window.wbids_bob.reset();
        self.sendPing();
    }

    self.pingCallback = function(resp, time)
    {
        var data = eval('('+resp+')');

        /* update time before items */
        if(typeof data['time'] != 'undefined')
            self.setTime(parseFloat(data['time']) + time / 2);

        for(var id in data) {
            if(typeof self.items[id] != 'undefined')
                self.items[id]['callback'](data[id]);
        }
    }
    self.request.setCallback(self.pingCallback);
    self.info_request.setCallback(self.pingCallback);

    self.bidCallback = function(resp, time)
    {
        var data = eval('('+resp+')');
        for(var id in data) {
            if(typeof self.items[id] != 'undefined')
                self.items[id]['callbackBid'](data[id]);
        }
    }
    self.bid_request.setCallback(self.bidCallback);

    self.time = function()
    {
        delete self.now;
        self.now = new Date();
        return (self.now.getTime() / 1000) + self.time_shift;
    }

    self.setTime = function(server_time)
    {
        /* FIXME: this should drift in the background without user noticing */
        self.time_shift -= WBIDS.time() - server_time;
        dprint("setTime("+server_time+") new shift: "+self.time_shift);
    }

    /* runs one tick, calls update() on all items */
    self.run = function()
    {
        var now = self.time();

        /* stop ticking if the player is idling */
        if(now > self.last_active + idle_time && idle_time > 0) {
            if(self.clock)
                self.clock.stop();
            clearInterval(self.interval);

            try {
                if (idle_page > 0) {
                    window.location="content.php?p=idle";
                } else if(user_login) {
                    popup_data('<h2 class="text-align: center">'+lang('CONNECTION_TIMED_OUT')+'</h2>');
                } else {
                    popup_data('<h2 class="text-align: center">'+lang('CONNECTION_TIMED_OUT_PLEASE_LOGIN')+'</h2>');
                }
            } catch(e) {
                alert('You have been idling too long. Connection closed.');
            }
            return;
        }

        /* run update() method on all items every second */
        for(var id in self.items) {
            var item = self.items[id];
            item.update(now);
        }

        /* send our "queue" every 3 seconds */
        if(now - self.last_request > self.ping_interval) {
            self.sendPing();
            if(self.single)
                self.info_request.run();
            self.ping_interval = 3;
        }

        /* send agent request every 120+rand(0-60) seconds */
        if(now - self.last_agent_request > self.agent_interval) {
            self.agent_request.run();
            self.last_agent_request = now;
            self.agent_interval = 120;
        }
    }

    self.setPingInterval = function(s)
    {
        self.ping_interval = s;
    }

    self.sendPing = function()
    {
        self.request.run(self.single);
        self.last_request = self.time();
    }

    self.bid = function(id)
    {
        self.bid_request.clearObjects();
        self.bid_request.addObject(self.items[id]);
        self.bid_request.run();
        //$('a:first').focus();
    }

    self.getId = function()
    {
        try {
            return self.itemFunc[0];
        } catch(e) {
            return null;
        }
    }

    self.agentRequest = function()
    {
        var tmp = new Object();
        try {
            tmp['func'] = self.itemFunc[0];
        } catch (e) {}
        return tmp;
    }

    self.agentCallback = function(resp, time)
    {
        var data = eval('('+resp+')');
        try {
            if(!self.single) {
                for(var i in data['items']) {
                    var item_id = data['items'][i];
                    if(typeof self.items[item_id] == 'undefined')
                        self.refresh();
                }
            }
        } catch(e) { }

        try {
            if(self.version && self.version != data['version'])
                window.location.reload();
            self.version = data['version'];
        } catch(e) { }

        if(self.clock) {
            self.clock.setTime(data['time']);
        }

        if(typeof data['message'] == 'string')
            wbids_info(data['message']);

        /* if the clients clock was way in the future, workaround it */
        if(self.last_agent_request > WBIDS.time())
            self.last_agent_request = WBIDS.time();
    }
    self.agent_request.setCallback(self.agentCallback);

    window.onload = function() {
        /* initialize misc stuff */
        try {
            if(typeof init_debug_console == 'function')
                init_debug_console();
        } catch (xd) {
        }

        /* init messaging here (the bid popup) */
        try {
            if(typeof wbids_message_init == 'function')
                wbids_message_init(1000);
            else
                dprint("Warning: wbids_message_init was not defined");
        } catch (xd) {
            dprint("Warning: wbids_message_init was not defined");
        }

        /* fix our own clock immediately, idle kicker would activate if your clock was way in the past */
        if(typeof server_time == 'number')
            self.setTime(server_time);

        /* start servertime tick */
        try {
            if(typeof Clock == 'function' && document.getElementById('clock') != null) {
                self.clock = new Clock(document.getElementById('clock'));

                if(typeof server_time == 'number' && typeof timezone_offset == 'number') 
                    self.clock.setTime(server_time + timezone_offset);

                self.clock.run();
            } else {
                dprint("Warning: Clock was not defined");
            }
        } catch (xd) {
            dprint("Warning: wbids_message_init was not defined");
        }

        dprint('calling wbids_init(), let the game begin');

        /* call page init */
        try {
            if(typeof wbids_init == 'function')
                self.itemFunc = wbids_init();
            else
                dprint("Warning: wbids_init was not defined");
        } catch (xd) {
            dprint("Warning: wbids_init was not defined");
        }

        try {
            if(typeof self.itemFunc != 'object')
                dprint("Warning: no itemFunc returned! The page will not auto-refresh.");
        } catch (xd) {
            dprint("Warning: wbids_init was not defined");
        }

        /* call custom init */
        try {
            if(typeof wbids_custom_init == 'function')
                wbids_custom_init();
            else
                dprint("No custom init function");
        } catch (xd) {
            dprint("Warning: wbids_init was not defined");
        }

        /* start idle counter */
        try {
            window.onmousemove = self.activity;
            self.last_active = self.time();
            dprint("Idler events attached at "+self.last_active+".");
        } catch(xd) {
            dprint("Failed to add idler events.");
        }

        self.agent_request.addObject(self);

        dprint('Starting to tick items');
        self.run();
        self.interval = setInterval(self.run, self.tick);
    }

    self.popupCheckout = function(bank, amount, instant)
    {
        var params = 'popup=true';
        if(typeof bank == 'string' && bank.length > 0)
            params += '&bank='+bank;
        if(typeof amount == 'number' && amount > 0)
            params += '&amount='+amount;
        if(typeof instant == 'boolean' && instant)
            params += '&instant=true';

        var width = parseInt($(window).width() * 0.8);
        var height = parseInt($(window).height() * 0.8);
        var wtop = parseInt(screen.height / 2 - height / 2);
        var wleft = parseInt(screen.width / 2 - width / 2);
        window.open('buy_select_bidpack.php?'+params, 'wBidsPopupCheckout', 'scrollbars=1,toolbar=0,location=0,menubar=0,resizable=1,width='+width+',height='+height+',top='+wtop+',left='+wleft);
    }
}

window.WBIDS = new wBids(50);

function BidItem(id)
{
    var self = this;

    self.id = id;
    self.elements = new Array();
    self.data = false;

    self.getId = function() {return self.id;}
    self.p_price = null;
    self.p_pause = null;
    self.time_refresh = false;
    self.last_update = false;
    self.need_info = false;
    self.last_seconds_left = -1;

    self.single = false;
    self.setSingle = function(yes)
    {
        self.single = yes;
        if(yes)
            self.need_info = true;
    }

    self.clock = false;
    self.setClock = function(func)
    {
        self.clock_perc = -1;
        self.clock = func;
    }

    /* return true/false do we need new data */
    self.needPing = function()
    {
        try {
            // no reping if item is not going to be active anymore
            if(self.data['p_pause'] == 'sold')
                return false;
        } catch(e) { }
        return self.time_refresh < WBIDS.time();
    }

    self.needInfo = function()
    {
        var tmp = new Object();
        tmp['id'] = self.id;
        return (self.need_info ? tmp : false);
    }

    /* update clocks, called every 'tick' */
    self.update = function(now)
    {
        self.last_update = now;

        if(!self.data)
            return;

        try {
            // nothing to update if not really active right now
            if(self.data['p_pause'] != 'none' && !(prebid && self.data['p_pause'] == 'not_yet'))
                return false;
        } catch(e) { }

        var seconds_left = self.data['p_time_stop'] - now;
        /* we can tick to negative side, so prevent displaying negative time */
        if(seconds_left < 0)
            seconds_left = 0;

        if(seconds_left < 1 && self.data['p_pause'] == 'none') {
            self.elements['seconds_left'].innerHTML = '<span class="ajaxmsg">'+lang('CHECKING')+'</span>';
            self.time_refresh = 0;
            // request ping to happen as soon as possible
            WBIDS.setPingInterval(1);
        } else {
            if(seconds_left < self.last_seconds_left || self.last_seconds_left < 0) {
                if(seconds_left < time_low_seconds) {
                    $("#seconds_left"+self.id).addClass("time_low");
                }
                self.updateElement(self.elements['seconds_left'], 'seconds_left', seconds_left);
                self.last_seconds_left = seconds_left;
            }
        }
    }

    /* updates one element value with custom printing */
    self.updateElement = function(el, name, value)
    {
        switch(name) {
            case 'p_price':
                /* calling effect when updating price */
                if(self.p_price != value) {
                    wbids_bobprice(self.id, value);
                    if(self.single)
                        self.need_info = true;
                    self.p_price = value;
                }
                return;
            case 'seconds_left':
                if(typeof wbids_custom_seconds_left == 'function') {
                    var new_val = wbids_custom_seconds_left(self);
                    if(new_val != false) {
                        value = new_val;
                        break;
                    }
                }

                if(self.data['p_pause'] == 'sold') {
                    $("#seconds_left"+self.id).removeClass("time_low");
                    value = '<span class="ajaxmsg">'+lang('SOLD')+'</span>';
                    if(self.clock) {
                        if(self.clock_perc != 100) {
                            self.clock_perc = 100;
                            self.clock.setPercent(100);
                        }
                    }
                    break;
                } else if(self.data['p_pause'] == 'wait') {
                    value = '<span class="ajaxmsg">'+lang('WAIT')+'</span>';
                    if(self.clock) self.clock.setPercent(0);
                    break;
                } else if(self.data['p_pause'] == 'forced' || self.data['p_pause'] == 'nightly') {
                    if (self.data['p_last_bidder_name'] == null)
                        value = self.data['time_raise'];
                    else
                        value = self.data['p_seconds_left'];
                } /* else if(self.data['p_pause'] == 'nightly') {
                    value = '<span class="ajaxmsg">'+lang('NIGHTLY')+'</span>';
                    break;
                } */ else if(self.data['p_pause'] == 'not_yet') {
                    if (prebid) {
                        /* update always in prebid */
                        self.last_seconds_left = -1;
                    } else {
                        value = '<span class="opens">'+lang('NOT_YET')+'</span>';
                        break;
                    }
                }
                if(value > self.last_seconds_left && self.last_seconds_left > -1 && self.data['p_pause'] == 'none')
                    return;

                /* only under 10 seconds we care about more accuracy than a second (this gains a lot of performance!) */
                var tmp;
                if(value < 10 && use_millisecond) {
                    tmp = parseInt(value * 10);
                } else {
                    tmp = parseInt(value);
                }

                if(el.value_save == tmp)
                    return;
                el.value_save = tmp;

                if(self.clock) {
                    if(value > self.data['time_raise'])
                        var clock_perc = 0;
                    else
                        var clock_perc = 100 - parseInt((value / self.data['time_raise']) * 100);
                    if(clock_perc != self.clock_perc) {
                        self.clock_perc = clock_perc;
                        self.clock.setPercent(self.clock_perc);
                    }
                }

                /* note: this falls trough as it should */
            case 'time_raise':
                value = formatTime(value);
                break;
            case 'p_last_bidder_name':
                if(value == null || value == '') {
                    /* when no bidder and in nightly pause, show open time */
                    if(self.data['p_pause'] == 'nightly') {
                        value = self.data['time_start_str'];
                    }
                    if(self.data['p_pause'] == 'wait') {
                        /* when open but no bidders, show open text */
                        value = lang('OPEN');
                    }
                    if(self.data['p_pause'] == 'not_yet') {
                        /* when waiting for first activation, show start time */
                        value = self.data['time_start_str'];
                    }
                } else if(user_profile && user_login) {
                    value = '<a href="profile_view.php?a_username='+value+'">'+value+'</a>';
                }
                break;
        }

        el.innerHTML = value;
    }

    /* load data from an Array of values returned from ping request */
    self.callback = function(values)
    {
        if (typeof values['active_amount'] != 'undefined') {
            var active_el = document.getElementById('active_users');
            if (active_el != null) {
                active_el.innerHTML = parseInt(values['active_amount']);
            }
        }
        if (typeof values['bot_bids'] != 'undefined') {
            var botbids_el = document.getElementById('botBids');
            if (botbids_el != null) {
                botbids_el.innerHTML = parseInt(values['bot_bids']);
            }
        }
        var tmp_price = (typeof self.data['p_price'] == 'undefined')?0:self.data['p_price'];
        if(typeof values['bidders'] != 'undefined') {
            for(var i in values['bidders']) {
                var bidder = values['bidders'][i];
                var name_el = document.getElementById('item'+self.id+'bidder'+i+'_name');
                var type_el = document.getElementById('item'+self.id+'bidder'+i+'_type');
                var price_el = document.getElementById('item'+self.id+'bidder'+i+'_price');
                var time_el = document.getElementById('item'+self.id+'bidder'+i+'_time');
                if(name_el != null) {
                    if(user_profile && user_login)
                        name_el.innerHTML = '<a href="profile_view.php?a_username='+bidder['name']+'">'+bidder['name']+'</a>';
                    else
                        name_el.innerHTML = bidder['name'];
                }
                if (type_el != null) {
                    type_el.innerHTML = lang(bidder['type'].toUpperCase());
                }
                if (price_el != null && tmp_price) {
                    price_el.innerHTML = formatPrice(tmp_price);
                    tmp_price = parseFloat(tmp_price) - parseFloat(bidder['bid_raise_price']);
                    if (tmp_price < 0) tmp_price = 0;
                }
                if (time_el != null) {
                    var tmpHours = secondsToTime(bidder['time_create'])['hours'];
                    if (parseInt(tmpHours) < 10) tmpHours = '0' + tmpHours;
                    var tmpMinutes = secondsToTime(bidder['time_create'])['mins'];
                    if (parseInt(tmpMinutes) < 10) tmpMinutes = '0' + tmpMinutes;                    
                    time_el.innerHTML = tmpHours + ':' + tmpMinutes;
                }

            }
            delete values['bidders'];
            self.need_info = false;
            return;
        }

        var now = parseInt(WBIDS.time());

        /* if p_time_sold (last bid time) has changed, someone has bidded */
        if(self.data['p_time_sold'] != values['p_time_sold']) {
            self.last_seconds_left = -1;
            $("#seconds_left"+self.id).removeClass("time_low");
        }

        self.data = values;

        if(self.p_pause != self.data['p_pause']) {
            if(typeof wbids_custom_pause_callback == 'function')
                wbids_custom_pause_callback(self);
            self.p_pause = self.data['p_pause'];
        }

        /* if in prebid state, set p_time_stop to time_start + time_raise, it should "just work" */
        if (prebid && self.data['p_pause'] == 'not_yet') {
            self.data['p_time_stop'] = parseFloat(self.data['time_start']) + parseFloat(self.data['time_raise']);
            if(!$("#seconds_left"+self.id).hasClass("time_prebid"))
                $("#seconds_left"+self.id).addClass("time_prebid");
        }

        try {

            var item_value = document.getElementById('item_' + self.id + '_value');
            var item_price = document.getElementById('item_' + self.id + '_price');
            var item_saving = document.getElementById('item_' + self.id + '_saving');

            if (item_value) {
                item_value = item_value.innerHTML.replace(',', '.');
                if (item_value.search(/\d/) != -1)
                    item_value = item_value.substr(item_value.search(/\d/));
                item_value = parseFloat(item_value);
            }
            if (item_price)
                item_price.innerHTML = formatPrice(self.data['p_price']);
            if (item_saving)
                item_saving.innerHTML = formatPrice(item_value - self.data['p_price']);

            if(typeof wbids_savings_custom == 'function')
                wbids_savings_custom(self.id, item_value, self.data['p_price']);

        } catch (e) {}
        
        self.data['seconds_left'] = parseInt(self.data['p_time_stop']) - now;
        self.time_refresh = now + getRefreshTime(self.data);

        if(self.data['time_opens'] == self.data['time_closes']) {
            self.data['time_open'] = '24h';
        } else {
            var opens = secondsToTime(self.data['time_opens']);
            var closes = secondsToTime(self.data['time_closes']);
            self.data['time_open'] = padNumber(opens['hours'])+':'+padNumber(opens['mins'])+' - '+padNumber(closes['hours'])+':'+padNumber(closes['mins']);
        }

        var tmp = new Date((parseInt(self.data['time_start']) + parseInt(timezone_offset))* 1000);
        self.data['time_start_str'] = tmp.getUTCDate()+"."+(tmp.getUTCMonth()+1)+". "+padNumber(tmp.getUTCHours())+":"+padNumber(tmp.getUTCMinutes());

        try {
            /* reload if item was not found, it was probably sold */
            if(values['error'])
                window.location.reload();
        } catch(e) { }

        /* when active, update all possible fields */
        for(var el_name in values) {
            var value = values[el_name];
            var el = false;
            if(typeof self.elements[el_name] == 'object') {
                el = self.elements[el_name];
            } else {
                self.elements[el_name] = document.getElementById(el_name+self.id);
                el = self.elements[el_name];
            }

            if(el) {
                /* setting a default value for saved value */
                el.value_save = null;
                self.updateElement(el, el_name, value);
            }
        }
    }

    self.needBid = function()
    {
        var tmp = new Object();
        tmp['id'] = self.id;
        return tmp;
    }

    self.callbackBid = function(values)
    {
        try {
            wbids_message(values['message']);
        } catch(e) { }

        try {
            // instant refresh on successful bid
            if(values['success']) {
                self.time_refresh = WBIDS.time();
                self.callback(values['data']);
            }
        } catch(e) { }

        try {
            if(values['bids']) {
                var el = document.getElementById('bids');
                if(el)
                    el.innerHTML = values['bids'];
            }
        } catch(e) { }
    }
}

