
currzIndex=1000;

function BuzzBite(data, settings)
{
    this._elBb;
    this._els = {};
    this.settings = {};
    //ablajev: loading flag
    this.loaded = false;
    this.url;

    // set
    settings = settings? settings : {};
    this.defSettings = {'sync': true, 'vote': true, 'viewComments': true, 'share': true, 'inap': true, 'add': true, 'remove': true, 'add_group': true, 'remove_group': true, 'group': true, 'mag': true};
    for (k in this.defSettings) {
        this.settings[k] = (settings[k] !== undefined)? settings[k] : this.defSettings[k];
    }

    if (typeof(data) == "string" || typeof(data) == "number") {
        this.BB_id = Number(data);
        this.data = {};
    } else {
        this.data = data;
        this.BB_id = ("BB_id" in data)? data.BB_id : undefined;
    }

    // init html
    if (document.getElementById("bb_" + this.BB_id).innerHTML) {
        this._hInit();
    }

    // set zIndex
    this._els.buzzbite.style.zIndex = --currzIndex;

    // register instance
    BuzzBite._registry.instances[this.BB_id] = this;

    // unless<h2></h2> individual...
    if (this.settings.sync != false && this.closed == false) {
        // run syncronizer if not
        if (! BuzzBite.syncronizer) {
            BuzzBite.syncronizer = new BbSync([this.BB_id], BDP.syncTime);
            BuzzBite.syncronizer.start();
        } else {
            BuzzBite.syncronizer.add(this.BB_id);
        }
    }
    if(typeof(this._els.bbLoading) != 'undefined') {
        this._els.bbLoading.style.display='none';
    }
    this.loaded = true;
}

BuzzBite.prototype._hInit = function ()
{
    var oThis = this;
    // bb
    this._els["buzzbite"] = document.getElementById("bb_" + this.BB_id);
    this._els["bbsub"] = this._els["buzzbite"].getElementsByTagName("div")[0];

    // disabled - vote only
    if (this._els["bbsub"].className.indexOf("disabled") != -1) {
        this.disabled = true;
    }

    // def
    if (! this.data.answer) {
        this.data.answer = {};
    }
    if (! this.data.options) {
        this.data.options = {};
    }
    if (! this.data.BB_type) {
        this.data.BB_type = (this._els["bbsub"].className.indexOf("private") == -1)? "public" : "private";
    }
    if (! this.data.pie) {
        this.pie = {};
    }

    // bb els
    var els = this._els["buzzbite"].getElementsByTagName("*");
    for (var i=0; i<els.length; i++) {
        if (els[i].className) {
            this._els[ els[i].className.split(' ')[0].replace(/-/g, "_") ] = els[i];
        }
    };
    this._els["img"] = this._els["buzzbite"].getElementsByTagName('img')[0];

    // remove qeustion link if js enabled (?)
    var qlink = this._els.question.getElementsByTagName("a");
    if (qlink && qlink[0]) {
        this.url = qlink[0].href;
        this._els.question.innerHTML = qlink[0].innerHTML;
    }
    
    // closed ?
    var m = this._els.closing.title.match(/\d+\/\d+\/\d+/);
    this.closed = m? m[0] : false;

    // bb but
    this._evtMethod("bb_but_com", "click", "viewComments", null, true);
    this._evtMethod("bb_but_share", "click", (document.getElementById("sharePopup")? "advshare" : "share"), null, true);
    this._evtMethod("bb_but_inap", "click", "inap", null, true);
    this._evtMethod("bb_but_add", "click", "add", null, true);
    this._evtMethod("bb_but_remove", "click", "remove", null, true);
    this._evtMethod("bb_but_add_group", "click", "add_group", null, true);
    this._evtMethod("bb_but_remove_group", "click", "remove_group", null, true);
    this._evtMethod("bb_but_group", "click", "group", null, true);
    this._evtMethod("bb_but_mag", "click", "mag", null, true);
    //this._evtMethod("bb_but_toggle_vac", "click", "toggleVac", null, true);
    if(oThis._els.bb_vac) {
        oThis._els.buzzbite.onmouseover = function() {
            oThis.toggleVac('show');
        }
        oThis._els.buzzbite.onmouseout = function() {
            oThis.toggleVac('hide');
        }
    }
    // BuzzBite Options
    this._els["options"] = new Array();
    var els = this._els["legend"].getElementsByTagName("li");
    for (var i=0; i<els.length; i++) {
        this._els["options"][i] = new Array();
        this._els["options"][i]['li'] = els[i];
        // ff patch
        if (this._els["options"][i]['li'].getElementsByTagName("a").length > 1) {
            this._els["options"][i]['li'].innerHTML = this._els["options"][i]['li'].innerHTML.replace(/<\/a>(.*)<a [^>]*>/i, "$1")
        }
        this._els["options"][i]['a'] = this._els["options"][i]['li'].getElementsByTagName("a")[0];
        var BBO_id = Number(this._els["options"][i]['li'].id.slice(4));
        this._evtMethod(this._els["options"][i]['a'], "click", "vote", [BBO_id], true);

        // populate opts
        if (! this.data.options.BBO_id) {
            this.data.options[BBO_id] = this._els["options"][i]['a'].childNodes[1].nodeValue;
        }

        // populate answer
        if (! this.data.answer.BBO_id && this._els["options"][i]['li'].className.indexOf("selected") != -1) {
            this.data.answer.BBO_id = BBO_id;
            this.data.answer.BBO_text = this.data.options[BBO_id];
            this.data.answer.BBO_n = i+1;
        }
    }
    // Chart - hbars
    if (this._els["hbars"]) {
        this._els["bars"] = this._els["hbars"].getElementsByTagName("div");
    }
    if (this._els["pie"]) {
        this.pie.div = this._els["pie"];
        this.pie.img = this._els["pie"].getElementsByTagName("img")[0];
        var matches = this.pie.img.src.match( /^(.*)\/(\d{1,2})\/(\d{1,3})\.(\w{1,4})$/i )
        this.pie.path = matches[1];
        this.pie.ics = matches[2];
        this.pie.percent = Number(matches[3]);
        this.pie.ext = matches[4];
    }
}
BuzzBite.prototype._evtMethod = function (el, evt, method, params, stop)
{
    if (! el) return;
    if (typeof el == "string") {
        if (! this._els[el]) {
            return;
        }
        el = this._els[el];
    }
    if (el.attachEvent) {
        el.attachEvent("on"+evt, f);
    } else if (el.addEventListener) {
        el.addEventListener(evt, f, true);
    }
    var oThis = this;
    var params = params? params : [];
    function f (e) {
        e = e? e : window.event;
        if (stop) {
            if (e.preventDefault) {
                e.preventDefault();
            } else {
                e.returnValue = false;
            }
        }
        if (! method) {
            return;
        }
        if (typeof method == "string") {
            if (oThis.settings[method] === false) {
                return; // disabled
            }
            method = oThis[method];
        }
        method.apply(oThis, params);
    }
}


BuzzBite.prototype.toggleVac = function (showMe)
{
    var oThis = this;
    if (!oThis.loaded) {
        return false;
    }
    if(typeof('showMe')=='undefined')
    {
        if(typeof(this._vac_status)=='undefined')
        {
            this._vac_status='show';
        }
        else if(this._vac_status=='hide')
        {
            this._vac_status='show';
        }
        else if(this._vac_status=='show')
        {
            this._vac_status='hide';
        }
    } else {
        this._vac_status=showMe;
        oThis._els.bb_vac_content.inneHTML+='s: '+showMe;
    }
    var _vacShow = function() {
        var _elh = parseInt(oThis._els.bb_vac.style.height.substr(0,oThis._els.bb_vac.style.height.length-2));
            if(isNaN(_elh)) _elh=0;
            _elh=_elh+6;
            if(_elh>54)
            {
                if(typeof(oThis._updateStatViewVacFlag)=='undefined')
                {
                    oThis.updateStatViewVac(oThis._els.bb_but_toggle_vac);
                    oThis._updateStatViewVacFlag=true;
                }
                window.clearInterval(oThis._vacShowInterval);
                return;
            }
            oThis._els.bb_vac.style.height=_elh+'px';
            //oThis._els.bb_vac_content.style.height=_elh+'px';

            if(_elh>8) oThis._els.bb_vac.style.display='block';
            if(_elh>50) oThis._els.bb_vac_content.style.display='block'
        }

    var _vacHide = function()
    {
        var _elh = parseInt(oThis._els.bb_vac.style.height.substr(0,oThis._els.bb_vac.style.height.length-2));
        if(isNaN(_elh)) _elh=0;
        _elh=_elh-6;
            oThis._els.bb_vac.style.height=_elh+'px';
            //oThis._els.bb_vac_content.style.height=_elh+'px';
        if(_elh<6)
        {
            window.clearInterval(oThis._vacHideInterval);
            oThis._els.bb_vac.style.display='none';
        }
        if(_elh<50) oThis._els.bb_vac_content.style.display='none';
    }
    if(this._vac_status == 'show')
    {
        if(typeof(oThis._vacHideInterval)!='undefined' && oThis._vacHideInterval > 0)
        {
            window.clearInterval(oThis._vacHideInterval);
        }
        oThis._vacShowInterval = window.setInterval(_vacShow, 50);
    }
    if(this._vac_status == 'hide')
    {
        if(typeof(oThis._vacShowInterval)!='undefined' && oThis._vacShowInterval > 0)
        {
            window.clearInterval(oThis._vacShowInterval);
        }
        oThis._vacHideInterval = window.setInterval(_vacHide, 50);
    }
}

BuzzBite.prototype.viewComments = function ()
{
    var params = {};
    /*
    if (BDP.C_id) {
        params['C_id'] = BDP.C_id;
    }
    params['BB_id'] = this.BB_id;
    params['hide_buttons'] = 1;
    params['addComment'] = 1;

    var m = document.location.href.match( /[\\?&]back_url=([^&#]+)/ );
    if (m) {
        params['back_url'] = unescape(m[1]);
    } else {
        params['back_url'] = document.location.href;
    }
    
    BDP.go('buzzbite', params);
    */
    params['comment'] = 1;
    BDP.go(this.url, params);
}

BuzzBite.prototype.share = function ()
{
    BDP.go('share', {'BB_id': this.BB_id});
}
BuzzBite.prototype.advshare = function ()
{
    BuzzBite.SharePopup.Attach(this.BB_id);
}
BuzzBite.SharePopup =
{
    BB_id: null,
    popup: null,
	html: "",
    links: {},
    c2cEnabled: null,

    onshow: function (){},
    onclose: function (){},

    Attach: function  (BB_id)
    {

		// init
        if (! BuzzBite.SharePopup.html) {
            BuzzBite.SharePopup.c2cEnabled = swfobject.hasFlashPlayerVersion("7.0.0"); // && !swfobject.hasFlashPlayerVersion("10.0.0");
            if (! BuzzBite.SharePopup.c2cEnabled) {
                document.getElementById("c2c").style.visibility = "hidden";
            }
			var t = document.getElementById("sharePopup");
			BuzzBite.SharePopup.html = t.innerHTML;
			t.parentNode.removeChild(t);
        }
		// remove old
		BuzzBite.SharePopup.Remove(true);

		// set new
		BuzzBite.SharePopup.BB_id = BB_id;
		BuzzBite.SharePopup.popup = document.createElement('div');
		BuzzBite.SharePopup.popup.id = "sharePopup";
		BuzzBite.SharePopup.popup.className = "popup";
		//BuzzBite.SharePopup.style.display = "none";
		BuzzBite.SharePopup.popup.innerHTML = BuzzBite.SharePopup.html;

        // set links
        var links = BuzzBite.SharePopup.popup.getElementsByTagName('a');
        for (var i=0; i<links.length; i++) {
            BuzzBite.SharePopup.links[links[i].className] = links[i];
        }
        BuzzBite.SharePopup.links.www.href = BDP.go("share", {BB_id: BuzzBite.SharePopup.BB_id, view: "post", back_url: document.location.href}, true);
        BuzzBite.SharePopup.links.mail.href = BDP.go("share", {BB_id: BuzzBite.SharePopup.BB_id, view: "mail", back_url: document.location.href}, true);
		BuzzBite.SharePopup.links.www.onclick = BuzzBite.SharePopup.links.mail.onclick = function ()
		{
			BuzzBite.SharePopup.Remove();
		}
		var bb = BuzzBite.GetInstance(BB_id);
		var title = BDP.getMessage("share_title", [bb._els.question.innerHTML]);
		//url = "http://www.buzzdash.com/"; 
		//var url = document.location.href.replace(/index.php.*/, "");
        //url += BDP.go("buzzbite", {BB_id: BuzzBite.SharePopup.BB_id}, true);
        var url = bb.url;
		BuzzBite.SharePopup.links.digg.href = "http://digg.com/submit?url=" + encodeURIComponent(url) + "&title=" + encodeURIComponent(title);
		BuzzBite.SharePopup.links.delicious.href = "http://del.icio.us/post?v=4&noui&jump=close&url=" + encodeURIComponent(url) + "&title=" + encodeURIComponent(title);
		BuzzBite.SharePopup.links.reddit.href = "http://www.reddit.com/submit?url=" + encodeURIComponent(url) + "&title=" + encodeURIComponent(title);
		BuzzBite.SharePopup.links.su.href = "http://www.stumbleupon.com/submit?url=" + encodeURIComponent(url);
		var ext = ["digg", "delicious", "reddit", "su"];
		for (var i=0; i<ext.length; i++) {
			BuzzBite.SharePopup.links[ext[i]].target = "_blank";
			BuzzBite.SharePopup.links[ext[i]].onclick = BuzzBite.SharePopup.Remove;
		}
        
        // append
        bb._els.buzzbite.appendChild(BuzzBite.SharePopup.popup);
		bb._els.bb_but_share.style.backgroundPosition = "left top";
		
		// c2c flash
        swfobject.embedSWF(BDP.assets + "/lang/" + BDP.lang + "/share_c2c.swf?val=" + encodeURIComponent(url), "c2c", "158", "22", "9", "#ffffff", {}, {allowscriptaccess: "always"}, { id:"c2c_movie", name:"c2c_movie" });
        
		bb._els.bb_but_share.blur();
        BuzzBite.SharePopup.onshow();


    },
    Remove: function (_auto)
    {
        if (! BuzzBite.SharePopup.BB_id || ! BuzzBite.SharePopup.popup.parentNode) {
            return;
        }
        BuzzBite.SharePopup.onclose();
        BuzzBite.SharePopup.popup.parentNode.removeChild(BuzzBite.SharePopup.popup);
        BuzzBite.GetInstance(BuzzBite.SharePopup.BB_id)._els.bb_but_share.style.backgroundPosition = "left bottom";
        BuzzBite.SharePopup.BB_id = null;
    }

    
}

BuzzBite.prototype.inap = function ()
{
    var BB_id = this.BB_id;
    // init inap Jsr (global)
    if (typeof(oJsr_inap) == "undefined") {
        oJsr_inap = new Jsr();
    }

    // onload - result
    oJsr_inap.onresults = function (oThis) {
        if (oThis.results.inap) {
            BDP.message('inap_done');
        } else {
            BDP.error('Can not mark as inappropriate BB_id: ' + BB_id);
        }
    };

    // call
    oJsr_inap.call('buzzbite', 'inap', {'BB_id': BB_id});
}

BuzzBite.prototype.add = function ()
{
    if (this.closed) {
        BDP.message('closed_option', [this.closed]);
        return;
    }
    
    var BB_id = this.BB_id;
    // check for active user
    if (!BDP.U_id) {
        BDP.go('mybuzz');
    }
    // init mybuzz Jsr (global)
    if (typeof(oJsr_mybuzz) == "undefined") {
        oJsr_mybuzz = new Jsr();
    }

    var oThis = this;

    // onload - result
    oJsr_mybuzz.onresults = function (oJsr) {
        if (oJsr.results.add) {
            oThis._els['bb_but_add'].style.display = 'none';
            oThis._els['bb_but_remove'].style.display = 'block';
            //if (oThis.results.add == 'already_added') {
            //    BDP.message('add_already');
            //} else {
            //    BDP.message('add_done');
            //}
        } else {
            BDP.error('Cannot add buzzbite to mybuzz page');
        }
    };

    // call
    oJsr_mybuzz.call('mybuzz', 'add', {'BB_id': BB_id});
}

BuzzBite.prototype.remove = function ()
{
    if (this.closed) {
        BDP.message('closed_option', [this.closed]);
        return;
    }
    
    var BB_id = this.BB_id;
    // check for active user
    if (!BDP.U_id) {
        return false;
    }
    // init mybuzz Jsr (global)
    if (typeof(oJsr_mybuzz) == "undefined") {
        oJsr_mybuzz = new Jsr();
    }

    var oThis = this;

    // onload - result
    oJsr_mybuzz.onresults = function (oJsr) {
        if (oJsr.results.remove) {
            if (BDP.pageName == 'mybuzz' && document.location.href.indexOf('mine') == -1) {
                document.location.href = document.location.href;
                return;
            }

            oThis._els['bb_but_remove'].style.display = 'none';
            oThis._els['bb_but_add'].style.display = 'block';
            //BDP.message('remove_done');
        } else {
            BDP.error('Cannot remove buzzbite from mybuzz page');
        }
    };

    // call
    oJsr_mybuzz.call('mybuzz', 'remove', {'BB_id': BB_id});
}

BuzzBite.prototype.add_group = function ()
{
    if (this.closed) {
        BDP.message('closed_option', [this.closed]);
        return;
    }
    
    var BB_id = this.BB_id;
    // check for active user
    if (!BDP.U_id) {
        BDP.go('groupbuzz');
        return;
    }

    // check vote
    if (!this.data.answer.BBO_id && !(this.cookieVote() && this.markVoted(this.cookieVote()))) {
        BDP.message('add_group_wo_vote');
        return;
    }

    // init groupbuzz Jsr (global)
    if (typeof(oJsr_groupbuzz) == "undefined") {
        oJsr_groupbuzz = new Jsr();
    }

    var oThis = this;

    // onload - result
    oJsr_groupbuzz.onresults = function (oJsr) {
        if (oJsr.results.add) {
            if (BDP.pageName == 'groupbuzz' || BDP.pageName == 'buzzbite') {
                var url = document.location.href;
                if (url.indexOf("listType") == -1) {
                    url = BDP.go(url, {listType: BDP.listType, C_id: BDP.C_id}, true);
                }
                document.location.href = url;
                return;
            }

            oThis._els['bb_but_add_group'].style.display = 'none';
            oThis._els['bb_but_remove_group'].style.display = 'block';
            //if (oThis.results.add == 'already_added') {
            //    BDP.message('add_already');
            //} else {
            //    BDP.message('add_done');
            //}
        } else {
            BDP.error('Cannot add buzzbite to groupbuzz page');
        }
    };

    // call
    oJsr_groupbuzz.call('groupbuzz', 'add', {'BB_id': BB_id});
}

BuzzBite.prototype.remove_group = function ()
{
    if (this.closed) {
        BDP.message('closed_option', [this.closed]);
        return;
    }
    
    var BB_id = this.BB_id;
    // check for active user
    if (!BDP.U_id) {
        return false;
    }
    // init groupbuzz Jsr (global)
    if (typeof(oJsr_groupbuzz) == "undefined") {
        oJsr_groupbuzz = new Jsr();
    }

    var oThis = this;

    // onload - result
    oJsr_groupbuzz.onresults = function (oJsr) {
        if (oJsr.results.remove) {
            if (BDP.pageName == 'groupbuzz' || BDP.pageName == 'buzzbite') {
                /*
                if (document.location.href.indexOf('?') != -1) {
                    document.location.href = document.location.href + '&removed=1';
                } else {
                    document.location.href = document.location.href + '?removed=1';
                }
                */
                var url = document.location.href;
                if (url.indexOf("listType") == -1) {
                    url = BDP.go(url, {listType: BDP.listType, C_id: BDP.C_id}, true);
                }
                document.location.href = url;
                return;
            }

            oThis._els['bb_but_remove_group'].style.display = 'none';
            oThis._els['bb_but_add_group'].style.display = 'block';
            //BDP.message('remove_done');
        } else {
            BDP.error('Cannot remove buzzbite from groupbuzz page');
        }
    };

    // call
    oJsr_groupbuzz.call('groupbuzz', 'remove', {'BB_id': BB_id});
}

BuzzBite.prototype.group = function ()
{
    // closed
    if (this.closed) {
        BDP.message('closed_option', [this.closed]);
        return;
    }
    
    var params = {};
    if (BDP.C_id) {
        params['C_id'] = BDP.C_id;
    }
    params['hide_buttons'] = 1;
    params['showNotes'] = 1;
    var m = document.location.href.match( /[\\?&]back_url=([^&#]+)/ );
    if (m) {
        params['back_url'] = unescape(m[1]);
    } else {
        params['back_url'] = document.location.href;
    }
    BDP.go(this.url, params);
}


BuzzBite.prototype.mag = function () // buzzcuts
{
    if (this.closed) {
        BDP.message('closed_option', [this.closed]);
        return;
    }
    
    var params = {};
    if (BDP.C_id) {
        params['C_id'] = BDP.C_id;
    }
    params['BB_id'] = this.BB_id;
    BDP.go('buzzcuts', params);
}

BuzzBite.prototype.updateStatViewVac = function (evt)
{
    var BB_id = this.BB_id;

    BBVAC_id = evt.id.slice(4);
    if(isNaN(parseInt(BBVAC_id))) return;
    //alert('id: '+BB_id+' -> BBVAC_id: '+BBVAC_id);
    // init mybuzz Jsr (global)
    if (typeof(oJsr_buzz) == "undefined") {
        oJsr_buzz = new Jsr();
    }

    oJsr_buzz.onresults = function (oJsr)
    {
        // check
        if (oJsr.results.updateStatViewVac === false) {
            BDP.error("Couldn't update VAC views.");
            return;
        }
    };
    var params = {
        'BB_id': BB_id,
        'BBVAC_id': BBVAC_id
    };
    var actions = ['updateStatViewVac'];
    // call
    oJsr_buzz.call('buzzbite', actions, params);
    //alert('id: '+BB_id+' -> BBVAC_id: '+BBVAC_id);
}

BuzzBite.prototype.vote = function (BBO_id)
{
    // if evt
    if (isNaN(BBO_id)) {
        var evt = BBO_id || event;
        var el = evt.target? evt.target : evt.srcElement;
        while (el.id.indexOf("bbo_") == -1 && el.parentNode) {
            el = el.parentNode;
        }
        if (!el) return;
        BBO_id = el.id.slice(4);
    }
    
    // closed
    if (this.closed) {
        BDP.message('closed_vote', [this.closed]);
        return;
    }
    // check vote
    if (this.data.answer.BBO_id) {
        BDP.message('already_voted', [this.data.answer.BBO_n, this.data.answer.BBO_text]);
        return;
    }
    // check cookie vote
    if (this.cookieVote() && this.markVoted(this.cookieVote())) {
        BDP.message('already_voted', [this.data.answer.BBO_n, this.data.answer.BBO_text]);
        return;
    }
    // check disabled
    if (this.disabled) {
        return;
    }
    // check user
    if (!BDP.U_id && !BDP.AU_id) {
        if (BDP._cookieDisabled) {
            BDP.message('cookie_vote');
        } else {
			var params = {};
			params['back_url'] = document.location.href;
			BDP.go("login", params);
        }

        return;
    }

    // init vote Jsr (global)
    if (typeof(oJsr_vote) == "undefined") {
        oJsr_vote = new Jsr();
    }
    if (oJsr_vote.isReady == false) {
        // another vote pending
        return;
    }

    // onload - mark and update
    var oThis = this;
    oJsr_vote.onresults = function (oJsr)
    {
        var BB_id = oJsr.params.BB_ids[0];
        var BBO_id = oJsr.params.BBO_id;

        // check
        if (oJsr.results.vote !== true) {
            BDP.error("Couldn't vote (vote method returned false)");
            return;
        }

        // mark
        oThis.markVoted(BBO_id);

        // update reults
        oThis.updateResults(oJsr.results.getResultsData[BB_id]);

        if (typeof(oThis.onvote) == "string")     oThis.onvote = new Function(oThis.onvote);
        if (typeof(oThis.onvote) == "function")   oThis.onvote(oJsr.results.vote);
    };

    // call
    var actions = ['vote', 'getResultsData'];
    var params = {
        'BBO_id': BBO_id,
        'BB_ids': [this.BB_id]
    };
    oJsr_vote.call('buzzbite', actions, params);

}

BuzzBite.prototype.cookieVote = function (BBO_id)
{
    if (BDP.U_id) {
        var cName = "_u_answers[" + BDP.U_id + "]";
    } else if (BDP.AU_id) {
        var cName = "_au_answers[" + BDP.AU_id + "]";
    } else {
        return;
    }
    try {
        var cValue = document.cookie.split(cName + "=")[1].split(';')[0];
        eval("var answers = {" + cValue + "}");
    } catch (e) {
        var cValue = "";
        var answers = {};
    }
    // Set
    if (BBO_id) {
        if (BBO_id in answers) {
            return false;
        }
        cValue += (cValue? "," : "") + this.BB_id + ":" + BBO_id;
        /*ie size lmit */ if (cValue.length > 4000) cValue = cValue.replace(/\d+?:\d+?,/, "");
        var expire = "";
        document.cookie = cName + "=" + cValue + expire + "; path=/; domain=" +  "." + document.location.hostname.replace(/^www\./, "");
        return true;
    }
    // else - Get
    return (this.BB_id in answers)? answers[this.BB_id] : false;
}

BuzzBite.prototype.markVoted = function (BBO_id)
{
    for (var i=0; i<this._els["options"].length; i++) {
        if (BBO_id == this._els["options"][i]['li'].id.slice(4)) {
            // set answer
            this.data.answer.BBO_id = BBO_id;
            this.data.answer.BBO_text = this._els["options"][i]['a'].childNodes[1].nodeValue;
            this.data.answer.BBO_n = i+1;
            this._els["options"][i]["li"].className += " selected";

            // save cookie for browser instances
            this.cookieVote(BBO_id);

            // disabled
            this._els['bbsub'].className += " disabled";

            // status
            return true;
        }
    } // else remove cookie and false status
    this.cookieVote(BBO_id, -1);
    return false;
}

BuzzBite.prototype.updateResults = function (data)
{
    if (! data || data.totalVotes == this._els['votes'].innerHTML) {
       return;
    }
    // answer
    if (! this.data.answer.BBO_id && data.answer) {
        this.markVoted(data.answer.BBO_id);
    } else if (! this.data.answer.BBO_id && this.cookieVote()) {
		// meanwhile vote
		this.markVoted(this.cookieVote());
	}
    // percents
    var p = data.results;
    if (this._els["percents"]) {
        this._els["percents"].innerHTML = p.join("%<br />") + "%";
    }
    // Chart
    if (this._els.bars) {
        // hbars
        //for (var i = 0; i < p.length; i++) this._els.bars[i].style.width = (p[i] + "%");
        this.setHbars(p);
    } else if (this.pie.img) {
        // pie
        this.setPie(p[0]);

    } else if (this._els["img"]) {
        // php img
        this.refreshImage(200);
    }


    // votes (text, numbers, blink)
    var votes = this._els['votes'].innerHTML;
    if (votes <= 1) {
        if (votes == 0) {
            var search = " " + BDP.messages['votes'] + " ";
            var replace = " " + BDP.messages['vote'] + " ";
        } else {
            var search = " " + BDP.messages['vote'] + " ";
            var replace = " " + BDP.messages['votes'] + " ";
        }
        this._els['votes'].nextSibling.nodeValue = this._els['votes'].nextSibling.nodeValue.replace(search, replace);
    }
    this._els['votes'].innerHTML = data.totalVotes;
    this.blinkVotes();
}

BuzzBite.prototype.setPie = function (percent)
{
    if (percent == this.pie.percent) {
        return;
    }
    // return this.pie.img.src = this.pie.path + "/" + this.pie.ics + "/" + percent + "." + this.pie.ext;

    // Play
    if (typeof(percent) == "undefined" && this.pie._set) {
        var oThis = this;
        var oSet = this.pie._set;

        var count = Math.abs(this.pie._set.last - this.pie._set.first);

        var step = this.pie._set.last > this.pie._set.first? +1 : -1;
        var cur = this.pie._set.first;
        var i = 0;
        var count = Math.abs(this.pie._set.last - this.pie._set.first);

    	function f ()
    	{
    	    do {
    	       cur += step;
    	       i++;
    	    }
    	    while ((! BuzzBite._registry.pies[oThis.pie.ics][cur] || ! BuzzBite._registry.pies[oThis.pie.ics][cur].complete) && (cur != oThis.pie._set.last) && i < count)
    	    oThis.pie.img.src = BuzzBite._registry.pies[oThis.pie.ics][cur].src;
            if (cur == oThis.pie._set.last) window.clearInterval(oThis.pie._set.interval);

    	}
    	if (this.pie._set.interval) window.clearInterval(this.pie._set.interval);
    	this.pie._set.interval = window.setInterval(f, 10);
        return;
    }

    // Init
    this.pie._set = {
        'startTime': (new Date()).getTime(),
        'intervalTime': 700,
        'last': Number(percent),
        'first': Number(this.pie.percent),
        'cur': Number(this.pie.percent),
        'level': 3
    };
    if (typeof(BuzzBite._registry.pies[this.pie.ics]) != "array") {
        BuzzBite._registry.pies[this.pie.ics] = new Array(100);
    }
    // Preload and Play
    this._preloadPies();
    window.setTimeout("BuzzBite.GetInstance(" + this.BB_id + ").setPie()", this.pie._set.intervalTime);
    return;
}

BuzzBite.prototype._preloadPies = function ()
{
    var steps =  getLevelSteps(this.pie._set.first, this.pie._set.last, this.pie._set.level);

    // most importand are last
    steps.push(this.pie._set.last);
    steps.reverse();

    // Img load
    var lastImg;
    for (var i=0; i<steps.length; i++) {
        var current = steps[i];
        if (! BuzzBite._registry.pies[this.pie.ics][current]) {
            BuzzBite._registry.pies[this.pie.ics][current] = new Image();
            BuzzBite._registry.pies[this.pie.ics][current].src = this._pieUrl(current);
            lastImg = BuzzBite._registry.pies[this.pie.ics][current];
        }
    }
    // level
    this.pie._set.level++;

    // if all (last) loaded do next level
    if (! lastImg) return;
    var oThis = this;
    lastImg.onload = function ()
    {
        if ((oThis.pie._set.level < 7) && ((new Date).getTime() - oThis.pie._set.startTime < oThis.pie._set.intervalTime)) {
            oThis._preloadPies();
        }
    }

}
function getLevelSteps (from, to, level)
{
    var steps = [];
    if (from > to) {
        var tmp = from;  from = to; to = tmp;
    }
    var dif = to - from;
    if (dif < 1) {
        return [];
    }
    if (level <= 1) {
        return [Math.round((from + to) / 2)];
    }
    if (Math.pow(2, level) > dif) {
        for (var i = 0; i < (dif-1); i++) {
            steps[i] = from + (i+1);
        }
    } else {
        steps =  getLevelSteps(from, Math.round((from + to) / 2), level - 1).concat(  [Math.round((from + to) / 2)] ).concat( getLevelSteps(Math.round((from + to) / 2), to, level - 1) );
    }
    if (tmp == to) {
        steps.reverse();
    }
    return steps;
}

BuzzBite.prototype._pieUrl = function (percent)
{
    percent = percent? percent : this.pie.percent;
    return this.pie.path + "/" + this.pie.ics + "/" + percent + "." + this.pie.ext;
}


BuzzBite.prototype.setHbars = function (percents)
{
    for (var i = 0; i < percents.length; i++) {
        //this._els.bars[i].style.width = (percents[i] + "%");
        var start = Number(this._els.bars[i].style.width.slice(0, -1));
        var end = percents[i];
        if (start == end) {
            continue;
        }
        var steps = Math.abs(start-end)/1;
        animateW(this._els.bars[i], start, end);
    }
}

/// animation
function animateW(el, start, end)
{
	if (el._interval) window.clearInterval(el._interval);

	if (start == end) {
	    return;
	} else if (start < end) {
	    var steps = end - start;
	    var step = +1;
	} else {
	    var steps = start - end;
	    var step = -1;
	}
	var cur = start;
	var i = 0;

	function f ()
	{
	    i++;
	    cur += step;
		el.style.width = cur + "%";
		if (cur == end || i >= steps) window.clearInterval(el._interval);
	}
	el._interval = window.setInterval(f, 10);
}

BuzzBite.prototype.refreshImage = function (timeout)
{
    if (timeout) {
        var oThis = this;
        return setTimeout(function(){ oThis.refreshImage.call(oThis) }, timeout);
    }
    this._els["img"].src = "assets/chart.php?BB_id=" + this.BB_id + "&t=" + ((new Date()).getTime());
}
BuzzBite.prototype.blinkVotes = function ()
{
    if (this._blinking) {
        return;
    }
    this._blinking = true;

    var oThis = this;
    var on = function ()
    {
        oThis._els['votes'].style.visibility = "visible";
        oThis._els['votes'].style.color = "#B55E00";
    }
    var off = function ()
    {
        oThis._els['votes'].style.visibility = "hidden";
    }
    var restore = function()
    {
        oThis._els['votes'].style.visibility = "visible";
        oThis._els['votes'].style.color = "";
        oThis._blinking = false;
    }
    for (var i=0; i<=4; i++) {
        if (i==4) {
            window.setTimeout(restore,  i*500+1500);
        } else {
            window.setTimeout(off,  i*500);
        }
        window.setTimeout(on,   i*500+250);
    }
}
BuzzBite.prototype.destroy = function ()
{
    BuzzBite.Destroy(this.BB_id);
}

//// static
BuzzBite._registry = {
    instances: {},
    pies: []
};
BuzzBite.Destroy = function (BB_id)
{
    BuzzBite.syncronizer.remove([BB_id]);
    delete(BuzzBite._registry.instances[BB_id]);
}
BuzzBite.GetInstance = function (BB_id)
{
    return BuzzBite._registry.instances[BB_id];
}
BuzzBite.SetResults = function (BB_id, data)
{
    var bb = BuzzBite.GetInstance(BB_id);
    bb.updateResults(data);
}
BuzzBite.RefreshImage = function (BB_id, timeout)
{
    var bb = BuzzBite.GetInstance(BB_id);
    bb.refreshImage(timeout);
}
BuzzBite.syncronizer = null;



//////
/**
* Sync interval
* @param array BB_ids   Array or single bb ids to sync
* @param int interval   Sync Interval. If <  assumed seconds els miliseconds
*/
function BbSync (BB_ids, interval)
{
    //this.BB_ids = (typeof(BB_ids) == "array")? BB_ids : [BB_ids];
    this.BB_ids = BB_ids;
    interval = interval || BDP.syncTime;
    this.interval = (interval < 100)? interval*1000 : interval;

    this._state;
    this._interval_id;
    this._oJsr = new Jsr();

    this.last_time;


    this.start = function ()
    {
        var oThis = this;
        function callSync ()
        {
            // ?time corection
            BbSync.Sync.call(oThis);
        }
        this._interval_id = setInterval(callSync, this.interval);
    }
    this.stop = function ()
    {
        clearInterval(this._interval_id);
        this._interval_id = undefined;
    }

    this.add = function (BB_ids)
    {
        BB_ids = (typeof(BB_ids) == "array")? BB_ids : [BB_ids];
        this.BB_ids = this.BB_ids.concat(BB_ids);
    }
    this.remove = function (BB_ids)
    {
        BB_ids = (BB_ids.constructor == Array)? BB_ids : [BB_ids];
        for (var i = 0; i < this.BB_ids.length; i++) {
            for (var j = 0; j < BB_ids.length; j++) {
                if (this.BB_ids[i] == BB_ids[j]) {
                    this.BB_ids.splice(i, 1);
                }
            }
        }
    }

}

/// static methods
/**
* Get data and update
* can be used both as static otr instance method (oses objects BB_ids and jsr object)
*/
BbSync.Sync = function (BB_ids)
{
    if (this.constructor == BbSync) {
        var oJsr = this._oJsr;
        BB_ids = this.BB_ids;
    } else {
        var oJsr = new Jsr();
    }

    //oJsr.onload = BbSync._jsrLoadHandler;
    oJsr.onresults = function (oJsr)
    {
        // update results
        for (var i=0; i<BB_ids.length; i++) {
            var BB_id = BB_ids[i];
            if (BB_id in oJsr.results.getResultsData) {
                BuzzBite.SetResults(BB_id, oJsr.results.getResultsData[BB_id]);
            }
        }
        // obj instance
        if (this.constructor == BbSync) {
            this.last_time = (new Date()).getTime();
        }
    }

    // call
    var params = {}
    params.BB_ids = BB_ids;
    oJsr.call('buzzbite', 'getResultsData', params);

}






/// JSR
/**
* Override JSR error - call BDP error with debug info
*/
Jsr.prototype.error = function (msg, desc)
{
    if (this.actions == "error") {
        return;
    }
    if (this.responseText == "") {
        if (this._xmlHttp) {
            try {
                var sep = "\n----------------------\n";
                var res = "STATUS:\n" + this._xmlHttp.status + " " + this._xmlHttp.statusText + sep + "HEADERS\n: " + this._xmlHttp.getAllResponseHeaders() + sep;
            } catch(e) {
                //
            }
            return;
        }
    }
    this.fireAction('onerror');
    BDP.error("JSR ERROR: " + msg, desc, {
        "file": this.file,
        "actions": this.actions,
        "params": this.params,
        "responseObj": this.responseObj,
        "responseText": this.responseText
    });
}

