String.prototype.leftPad = function (l, c) { return new Array(l - this.length + 1).join(c || '0') + this; }
Math.frac = function(v) { return v - Math.floor(v); }

function CO2monitorWidget(widget) {
    // store additional reference to myself
    // the signal handlers need it, because "this" will be reassigned by jQuery
    var self = this;

    this.widget = widget;

    this.dayFraction = function() {
        return (new Date() - this.day_start) / (86400 * 1000);
    }

    this.yearFraction = function() {
        return (new Date() - this.year_start) / (365.25 * 86400 * 1000);
    }

    this.getTextObject = function(text, css) {
        var o = $('<div style="position:absolute;width:200px;height:20px;letter-spacing:-0.1em;color:#003;text-align:center;font-weight:bold"></div>');
        o.html(text);
        if (css)
            o.css(css);

        return o;
    }

    this.loadFromServer = function(callback) {
        $.getJSON('/ajax/widget/', function(data) {
            self.init(data);

            if (callback)
                callback.apply(self);
        });
    }

    // counter panel
    this.activateCounter = function(panel) {
        if (!this.counterObjects)
            this.createCounter(panel);
        this.counterIntervalHandler();
        this.counterInterval = setInterval(this.counterIntervalHandler, 1000);
    }

    this.deactivateCounter = function() {
        clearInterval(this.counterInterval);
    }

    this.createCounter = function(widget_body) {
        var my_digits = [];
        var gl_digits = [];

        function createDigit(x, y) {
            var img = $('<img>');
            img.attr('src', '/media/images/widget/co2-monitor-widget_box-trans.png');
            img.css('position', 'absolute');
            img.css('left', x + 'px');
            img.css('top', y + 'px');
            img.css('background', 'url(/media/images/widget/co2-monitor-widget_numbers.jpg)');
            return img;
        }

        for(var i=0; i<5; i++) {
            var img = createDigit(23 + i * 18, 40);
            widget_body.append(img);
            my_digits.push(img);

            var img = createDigit(23 + i * 18, 125);
            widget_body.append(img);
            gl_digits.push(img);
        }

        for(var i=0; i<3; i++) {
            var img = createDigit(117 + i * 18, 40);
            widget_body.append(img);
            my_digits.push(img);

            var img = createDigit(117 + i * 18, 125);
            widget_body.append(img);
            gl_digits.push(img);
        }

        var timer = this.getTextObject('', {top:179, left:4, color:'#fff'});
        widget_body.append(timer);

        widget_body.append(this.getTextObject(gettext('My CO<sub>2</sub> emissions'), {top:19, left:6}));
        widget_body.append(this.getTextObject(gettext('Country average'), {top:106, left:6}));

        var thisyear = this.getTextObject('', {top:78, left:4, color:'#fff'});

        widget_body.append(thisyear);
        widget_body.append(this.getTextObject('kg', {top:48, left:171, width:20}));
        widget_body.append(this.getTextObject('kg', {top:133, left:171, width:20}));

        this.counterObjects = {
            timer: timer,
            my_digits: my_digits,
            gl_digits: gl_digits,
            thisyear: thisyear
        }
    }

    this.counterIntervalHandler = function() {
        self.counterObjects.timer.text(getDateString());
        self.counterObjects.thisyear.html(
            self.year + ' | ' + parseInt(self.emissions_thisyear) + ' kg CO<sub>2</sub>');
        setDigits(self.counterObjects.my_digits, self.emissions_thisyear_until_today + self.dayFraction() * self.emissions_today);
        setDigits(self.counterObjects.gl_digits, self.yearFraction() * self.emissions_average);
    }


    // thermometer
    this.activateThermometer = function(panel) {
        if (this.thermometerObjects)
            return;

        var to = function(top) {
            return {top: top, left: 0, width: 185, textAlign: 'right'};
        };

        panel.append(this.getTextObject(gettext('My commitments'), to(10)));
        panel.append(this.getTextObject(gettext('Next 12 months') + ': ' + this.measures_planned, to(32)));
        panel.append(this.getTextObject(gettext('Fulfilled') + ': ' + this.measures_realized, to(48)));

        panel.append(this.getTextObject(parseInt(this.measures_emissions) + ' kg CO<sub>2</sub>', {
            top: 101, left: 0, width: 185, textAlign: 'right'}));

        panel.append(this.getTextObject(this.year + ': ' + parseInt(this.emissions_thisyear) + ' kg CO<sub>2</sub>', {
            top: 172, left: 6, color: '#fff'}));
        panel.append(this.getTextObject(gettext('With commitments') + ': ' + parseInt(this.emissions_thisyear - this.measures_emissions) + ' kg', {
            top: 192, left: 6, color: '#bfb'}));


        this.thermometerObjects = true;
    }


    // thermometer
    this.activateGroup = function(panel) {
        if (this.groupObjects)
            return;

        var to = function(top, color) {
            var css = {top: top, left: 6};
            if (color)
                css.color = color;
            return css
        };

        panel.append(this.getTextObject(gettext('Total users'), to(45)));
        panel.append(this.getTextObject('' + parseInt(this.group_users), to(73, '#fff')));

        panel.append(this.getTextObject(gettext('Emissions') + ' - ' + gettext('median'), to(103)));
        panel.append(this.getTextObject(parseInt(this.group_emissions_median) + ' kg CO<sub>2</sub>', to(131, '#fff')));

        panel.append(this.getTextObject(gettext('Savings commitment all users'), to(161)));
        panel.append(this.getTextObject(parseInt(this.group_measures_emissions / 1000.0) + ' t CO<sub>2</sub>', to(189, '#fff')));

        this.groupObjects = true;
    }

    // facebook
    this.activateFacebook = function(panel) {
        if (this.facebookObjects)
            return;

        panel.append('' +
			'<div style="position:absolute;top:9px;left:12px;width:200px;height:184px" id="facebook-panel">' +
            '<div id="facebook-status-panel"><strong>Facebook</strong><br /><br/>' +
            '<a href="#" id="co2-facebook-connect-button"> <img id="fb_login_image" src="http://static.ak.fbcdn.net/images/fbconnect/login-buttons/connect_light_medium_long.gif" alt="Connect" /></a>' +
			'<br/><br/></div>' +
			'<div id="facebook-action-panel"></div></div>' +
			'');
        if(!this.user_authorized)
            $('#facebook-status-panel', panel).append(gettext('Please <a href="/en/account/login/">login</a> to connect your profile with facebook!'));
        var fb_api_key = self.fb_api_key;
		$('a#co2-facebook-connect-button',panel).click(function() {
			FB_RequireFeatures(["Api","XFBML"], function(){
		        FB.init(fb_api_key, "/fbconnect/xdreceiver.htm");
				FB.XFBML.Host.autoParseDomTree = false;
                api = FB.Facebook.apiClient;
                FB.Connect.requireSession(function(){
    				uid = api.get_session().uid;
    				fields = new Array('name');
                    $('div#facebook-status-panel').html('Connected!');
      				api.users_getInfo([api.get_session().uid],["first_name", "last_name", "locale"],function(result, exception){
    	            	$('div#facebook-status-panel').html('Hello' + ' ' + result[0].first_name + ' ' + result[0].last_name);
    	            });

    				jQuery.post('/fbconnect/connected/' + api.get_session().uid  + '/?session_key=' + api.get_session().session_key, {}, function(){
                        FB.Connect.showAddSectionButton("profile", document.getElementById("facebook-action-panel"));
                        //user_link = new FB.XFBML.ProfilePic(document.getElementById('facebook-status-panel'));
                        //FB.XFBML.Host.addElement(user_link);
                        //FB.XFBML.Host.parseDomTree();
    				});
                });
			});
		});

        this.facebookObjects = true;
    }

    // info
    this.activateInfo = function(panel) {
        if (this.infoObjects)
            return;

        panel.append('<div style="position:absolute;top:9px;left:12px;width:200px;height:184px">' +
            '<strong>About</strong><br />' +
            'This widget presents you a summary ' +
            'of your CO<sub>2</sub>-monitor account ' +
            'information and statistics.<br /><br />' +
            'You will be able to share this widget ' +
            'on Facebook or embed it on your personal' +
            ' web page</div>');

        this.infoObjects = true;
    }


    // face
    this.faceTexts = ['Very happy', 'Happy', 'Pleased', 'Patient', 'Annoyed', 'Sick'];
    this.activateFace = function(panel) {
        if (!this.faceObjects) {
            this.faceObjects = {};

            this.faceObjects.mood = this.getTextObject('', {top: 22, left: 6, color: '#fff'});
            panel.append(this.faceObjects.mood);

            panel.append(this.getTextObject('The World is:', {top: 6, left: 6}));
        }

        panel.css('background', 'url(/media/images/widget/co2m-widget-back-world' + this.earth_face + '.jpg)');
        this.faceObjects.mood.html(this.faceTexts[this.earth_face]);
    }


    // internal stuff
    this.panels = {
        counter: [this.activateCounter, this.deactivateCounter],
        thermo: [this.activateThermometer, null],
        group: [this.activateGroup, null],
        face: [this.activateFace, null],
        facebook: [this.activateFacebook, null],
        info: [this.activateInfo, null]
    };
    this.currentPanel = '';

    this.activatePanel = function(name) {
        if (this.currentPanel == name)
            return;

        var newPanel = self.widget.find('#b-' + name);

        if (!newPanel.length) {
            name = 'counter';
            newPanel = self.widget.find('#b-counter');
        }

        self.widget.find('div.body:visible').fadeOut();

        if (self.panels[self.currentPanel] && self.panels[self.currentPanel][1])
            self.panels[self.currentPanel][1].apply(self, [newPanel]);

        self.currentPanel = name;
        self.widget.removeClass('face counter thermo group facebook info').addClass(self.currentPanel);

        if (self.panels[self.currentPanel] && self.panels[self.currentPanel][0])
            self.panels[self.currentPanel][0].apply(self, [newPanel]);

        newPanel.fadeIn();

        $.cookie('co2m_widget_panel', name, {path: '/', expires: 365});
    }

    this.navClickHandler = function() {
        self.activatePanel(this.id.substr(2));
        return false;
    }

    this.init = function(data) {
        // these variables will be set at least partially from the outside
        this.year = data.year;
        this.emissions_thisyear = data.emissions_thisyear;
        this.emissions_thisyear_until_today = data.emissions_thisyear_until_today;
        this.emissions_today = data.emissions_today;
        this.emissions_lastyear = data.emissions_lastyear;
        this.emissions_average = data.emissions_average;

        this.measures_planned = data.measures_planned;
        this.measures_realized = data.measures_realized;
        this.measures_emissions = data.measures_emissions;

        this.group_users = data.group_users;
        this.group_emissions_median = data.group_emissions_median;
        this.group_measures_emissions = data.group_measures_emissions;

        this.earth_face = data.earth_face;

        this.user_authorized = data.user_authorized;
		// fb connect
		this.fb_api_key = data.fb_api_key;

        // helper methods
        this.year_start = new Date(this.year, 0, 1);
        this.today = new Date();
        this.day_start = new Date(this.year, this.today.getMonth(), this.today.getDate());

        // initialization code
        this.widget.find('.nav a').click(this.navClickHandler);

        this.currentPanel = '';
        this.counterObjects = false;
        this.thermometerObjects = false;
        this.groupObjects = false;
        this.facebookObjects = false;
        this.infoObjects = false;
        this.faceObjects = false;
        this.widget.find('>div[id^=b-]').remove();

        var nav = this.widget.find('.nav');
        for(var i in this.panels)
            nav.before('<div id="b-' + i + '" class="body"></div>');
        this.widget.find('div.body').hide();
    }
}

var co2m_widget;
$(window).load(function(){
    if (ie6)
        return;

    co2m_widget = new CO2monitorWidget($('#widget'));
    co2m_widget.loadFromServer(function(){
        co2m_widget.activatePanel($.cookie('co2m_widget_panel'));
    });

});

function reloadWidget() {
    co2m_widget.loadFromServer(function(){
        co2m_widget.activatePanel($.cookie('co2m_widget_panel'));
    });
}

function getDateString() {
    var d = new Date();

    return String(d.getDate()).leftPad(2, '0') + '.' +
        String(d.getMonth() + 1).leftPad(2, '0') + '.' +
        d.getFullYear() + ' ' +
        String(d.getHours()).leftPad(2, '0') + ':' +
        String(d.getMinutes()).leftPad(2, '0') + ':' +
        String(d.getSeconds()).leftPad(2, '0');
}

function setDigits(digits, value) {
    value *= 1000;

    var frac = Math.frac(value);
    var value = value - frac;
    var cprev = value % 10;

    for(var i=7; i>=0; --i) {
        var c = (value % Math.pow(10, 8 - i)) / Math.pow(10, 7 - i);
        var y;

        if (i == 7)
            y = 2 - (c + frac) * 22;
        else if (frac && cprev >= 9)
            y = 2 - (parseInt(c) + frac) * 22;
        else if (frac) {
            frac = 0;
            y = 2 - parseInt(c) * 22;
        } else
            y = 2 - parseInt(c) * 22;

        digits[i].css('backgroundPosition', '0px ' + y + 'px');

        cprev = c;
    }
}
