//  CSC Ratings Widget
//  Author: Kenneth Arnold <kcarnold@media> and Jason Alonso <jalonso@media>

// Extend the CSC Global Object
CSC.widgets.Ratings = function(config) {

// Import YUI components
var YUC = YAHOO.util.Connect;
var JSON = YAHOO.lang.JSON;
var YEvent = YAHOO.util.Event;
var Selector = YAHOO.util.Selector;

// Import CSC components
var go_json = CSC.go_json;
var session = CSC.session;

// Declare the default configuration
var _config = {
        rate_url: '/json/rate/',
        search_tags: '.rate',
        button_order: ['Agree', 'Disagree', 'Junk'],
        active_classes: {
                Agree: 'rate_up_act',
                Disagree: 'rate_down_act',
                Junk: 'rate_junk_act'
        },
        inactive_classes: {
                Agree: 'rate_up_inact',
                Disagree: 'rate_down_inact',
                Junk: 'rate_junk_inact'
        },
        id_prefix: 'rate_',
        tag_prefix: 'btn_',
        blank_img: '/media/blank.gif'
};

// Load the configuration
if( config == null ) config = {};
for( var k in _config )
        if( k in config )
                _config[k] = config[k];

/** Rating buttons */
var rating_buttons = new Object();

function rate(pred, value) {
        var request = {
                assertion_id: pred,
                rating_value: value
        };
        go_json(_config.rate_url, null, function(response) {}, request);
}


function click_button(id, tag) {
	if (!session.user_logged_in) {
		// FIXME: localize this.
		alert('You must be logged in to rate.\n\nClick Login or Sign Up.');
		return;
	}

	var parts = id.match( RegExp( '^' + _config.id_prefix + '(\\d+)$') );
	var pred_id = parts[1], which = tag;
	var set_id = _config.id_prefix+pred_id;
	var set = rating_buttons[set_id];
	
	var cur = set.get_current();
	if (cur == which) {
		// clicked an enabled rating. unrate.
		set.toggle(null);
		rate(pred_id, 'none');
	} else {
		// rating changed.
		set.toggle(which);
		rate(pred_id, which);
	}
}


function active(tag) { return _config.active_classes[tag]; }
function inact(tag) { return _config.inactive_classes[tag]; }

function over_button(id, tag) {
	if( tag == null ) return;
	$(_config.tag_prefix + id + '_' + tag).className = active(tag);
}
function out_button(id, tag) {
	if( tag == null ) return;
	if( tag == rating_buttons[id]._current ) return;
	$(_config.tag_prefix + id + '_' + tag).className = inact(tag);
}
function clickHandler(id, tag) { return function(e) { click_button(id, tag); }; }
function overHandler(id, tag) {	return function(e) { over_button(id, tag); }; }
function outHandler(id, tag) { return function(e) { out_button(id, tag); }; }

function make_buttons(container, id) {
	var set = rating_buttons[id];
	if (set == null) {
		rating_buttons[id] = set = new ButtonSet(id);
	}

	function make_button(id, tag) {
		var el=document.createElement('img');
		el.setAttribute('src', _config.blank_img);
		var btn_id = _config.tag_prefix + id+'_'+tag;
		el.setAttribute('alt', tag);
		el.setAttribute('title', 'Rate as '+tag);
		el.className = inact(tag);
		el.setAttribute('id', btn_id);
                YEvent.addListener(btn_id, 'click', clickHandler(id, tag));
                YEvent.addListener(btn_id, 'mouseover', overHandler(id, tag));
                YEvent.addListener(btn_id, 'mouseout', outHandler(id, tag));
		container.appendChild(el);
	}

	// Make new buttons
        for( var tag in _config.button_order )
                make_button(id, _config.button_order[tag]);
}

function ButtonSet(id) {
	this.id = id;
}
ButtonSet.prototype.toggle = function(tag) {
	var last = this._current;
	this._current = tag;
	over_button(this.id, tag);
	out_button(this.id, last);
};
ButtonSet.prototype.get_current = function() {
	return this._current;
};


var _ratings_initialized = false;
var _ratings_spans = [];
function init_ratings() {
        if( _ratings_initialized ) return load_ratings();
        else _ratings_initialized = true;
	_ratings_spans = Selector.query(_config.search_tags);
	for (var i=0; i<_ratings_spans.length; i++) {
		var span = _ratings_spans[i];
		var id = span.id;
		// create the buttons
		make_buttons(span, id);
                rating_buttons[id].toggle(null);
        }
        return load_ratings();
}

function load_ratings() {
	for (var i=0; i<_ratings_spans.length; i++) {
		var span = _ratings_spans[i];
		var id = span.id;
		// set the current one active as specified by data (a comment).
                var asrt_id = span.id.substring(5);
                get_rating(asrt_id, id, function(id, data) {
                        var cur;
                        switch(data) {
                        case 'none': cur = null; break;
                        case 'need_login':
                                session.user_logged_in = false;
                        default:
                                if( data in _config.active_classes )
                                        cur = data;
                                else cur = null;
                        }
                        rating_buttons[id].toggle(cur);
                });
	}
}

function get_rating(asrt_id, id, callback) {
        var handler = function(response) { callback(id, response['rating']); };
        go_json(_config.rate_url + asrt_id + '/', null, handler);
}

// Export methods and properties
this.init = init_ratings;
};
