/*
 * socratos-questions.js - File containing javascript functions for socratos questions.
 *
 * Add any action required at startup to the document ready function.
 * Please try adding jQuery javascript or non-library bound javascript.
 *
 */

/**
 * Defines if javascript random should be done or not on answers
 * (For example when going back to a question, the answers should be shown in 
 * the user chosen order and this variable will be overritten to 'true')
 * @author Andrei Ghiuta
 */
var noRandom = false;

/*
 * Escape text so it can be used in a jQuery find function
 * @param text String to replace characters from
 * @return text string
 */
function escapeName (text)
{
	text = text.replace('[', '\\[').replace(']', '\\]');
    return text;
}


/*
 * Replace illegal or deprecated characters in tag ids with valid characters.
 *
 * @param text string to replace characters from
 * @return text string
 */
function validId (text)
{
    text = text.replace(/\./, '_');
    return text;
}

/*
 * Create a random string
 *
 */
function randomString(length) {
    var chars = '0123456789ABCDEFGHIJKLMNPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split('');
    
    if (! length) {
        length = 6;
    }
    
    var str = '';
    for (var i = 0; i < length; i++) {
        str += chars[Math.floor(Math.random() * chars.length)];
    }
    return str;
}

/*
 * generate an id for an object not yet having an Id
 */
function generateId() {
    while (1) {
		// create new ID
		var generatedId = randomString(8);
		// check if id already in use
		var used = $('body').find('#'+generatedId);
		if (used.length == 0) {
			return generatedId;
		}
    }
    return false;
}


/*
 * Bind a click event on table cells containing only one checkbox or radiobutton
 * as click this object. If any other clickable objects (links, buttons, textarea's)
 * are present in the same cell, no event is bound to the cell.
 *
 * @author mike AT vervuren DOT com
 */
var CellClickToCheckboxRadio = function() {
    // find all checkboxes and radio buttons in this page
    var checkboxes = $(document).find(':checkbox,:radio');
    $.each(
        checkboxes,
        function () {
	    var checkbox = $(this);
		var cell = ' ';

		// find cell which is designed to be clicked
		if ($(checkbox).attr('id') != '') {
			var findId = '#boxfor_'+$(this).attr('id');
			findId = validId(findId);
			cell = $(findId);
			if (cell.length == 0) {
				cell = ' ';
			}
		}
		if (typeof(cell) === 'string' ) {
			// find the first parent table cell
			cell = $(checkbox).parents('td:first');
		}

	    if (cell.length ===1) {
			// check for other clickable objects in this cell
			var inputs = $(cell).find('input,textarea,button,a,select,option');
                
			if (inputs.length === 1) {
				$(cell).bind('click',
				function(event){
					if ($(checkbox).attr('disabled')=== true) {
						return;
					}
					if (event.target.type !== $(checkbox).attr('type')) {
							if ($(checkbox).attr('checked') === false) {
								$(checkbox).attr('checked', true);
							} else {
								// radio button can not be unset
								if ($(checkbox).attr('type') === 'checkbox') {
									$(checkbox).attr('checked', false);
								}
							}
						// run onclick event for input element
							$(checkbox).trigger('onclick');
						}
                    });
                    // change mouse pointer to indicate clickable content
//                    $(cell).css('cursor','pointer');

		    // get cell background-color
		    var originalcolor = $(cell).css('background-color');
		    var bgcolor = 'transparent';

		    var row = $(cell).parents('tr');
		    $.each(
			row,
			function() {
			    if ($(this).css('background-color') != 'transparent' && bgcolor === 'transparent' || bgcolor === 'rgba(0, 0, 0, 0)') {
				bgcolor = $(this).css('background-color');
			    }
			}
		    );

		    if (bgcolor === 'transparent' || bgcolor === 'rgba(0, 0, 0, 0)' || bgcolor === 'rgb(0, 0, 0)' ) {
			bgcolor = originalcolor;
		    }
		    var color = DarkerColor(bgcolor);
		    $(cell).hover(
			function(){
			    $(this).css('background-color', color);
			},
			function() {
			    $(this).css('background-color', originalcolor);
			}
		    );
                }
            }
        }
    );
};

/*
 * calculate a darker color for a given color in hex, rgb or rgba format
 */
function DarkerColor(rgb) {
    if (rgb === 'transparent') {
	return rgb;
    }

    var rgbvals = null;
    var rval = 0;
    var gval = 0;
    var bval = 0;
    var tval = 1;

    // check if color is in rgb or rgba format
    if (rgb.indexOf('rgb') === 0) {
	var rgbs = /rgba?\((.*?)\)/i.exec(rgb);
	if (rgbs) {
	    var realRGB = rgbs[1].toString();
	    rgbvals = realRGB.split(",",4);
	} else {
	    return 'transparent';
	}
	// read rgb values
	if (rgbvals.length > 2) {
	    rval = parseInt(rgbvals[0]);
	    gval = parseInt(rgbvals[1]);
	    bval = parseInt(rgbvals[2]);
	    tval = parseInt(rgbvals[3]);
	    if (tval === 0) {
		return 'transparant';
	    }
	} else {
		return 'transparant';
	}
    } else if (rgb.indexOf('#') === 0 ){
	if (rgb.length === 7) {
	    rgbvals = /\#([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})/i.exec(rgb);
	    rval = parseInt(rgbvals[1],16);
	    gval = parseInt(rgbvals[2],16);
	    bval = parseInt(rgbvals[3],16);
	} else if (rgb.length === 4){
	    rgbvals = /\#([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})/i.exec(rgb);
	    rval = parseInt(rgbvals[1]+rgbvals[1],16);
	    gval = parseInt(rgbvals[2]+rgbvals[2],16);
	    bval = parseInt(rgbvals[3]+rgbvals[3],16);
	} else {
	    return 'transparant';
	}
    } else {
	return 'transparant';
    }

    var reduce = 8;
    rval -= reduce; gval -= reduce; bval -= reduce;
    if (rval < 0 ) {rval += 50}
    if (gval < 0 ) {gval += 50}
    if (bval < 0 ) {bval += 50}
    
    var strColor = '#' + (
	rval.toString(16) +
	gval.toString(16) +
	bval.toString(16)
    ).toUpperCase();

    return strColor;
}

/*
 * function to randomize the child elements of an element  
 */
function randOrd() { 
	return (Math.round(Math.random())-0.5); 
}

$.fn.randomize = function() {
	var returnValue = false;
	$(this).each(function() {
		var $loopItem = $(this);
		var $children = $(this).children();
		var childCount = $children.length;

		if (childCount > 1) {
			$children.remove();
		
			var indices = new Array();
			var alwaysLast = new Array();
			for (i=0;i<childCount;i++) { 
				if ((childCount - i) <= alwaysLastCount) {
					alwaysLast[alwaysLast.length] = i;
				} else {
					indices[indices.length] = i;
				}
			}
			indices = indices.sort(randOrd);
			$.each(indices,function(j,k) { 
				$loopItem.append($children.eq(k)); 
			});
			$.each(alwaysLast,function(j,k) { 
				$loopItem.append($children.eq(k)); 
			});
		}
		returnValue = true;
	});
	return (returnValue == true);
}

/**
 * Find all checkboxes and radiobuttons in the body and replace them with an
 * alternate input element (a button). This button can be styled thus creating a
 * fancy form.
 * As an extra, if the checkbox or radiobutton is the only element in a tablecell,
 * the click event is bound to the tablecell.
 *
 * @author Mike Vervuren
 * @author Wim ...
 * @since 2010
 *
 */
function styleCheckboxesAndRadiobuttons()
{
        var elements = $('body').find(':checkbox,:radio');
        $.each(
            elements,
            function() {
                createAlternate($(this));
            }
        );
}

/*
 * Function to replace an checkbox with a button with a background image thus creating a nicer checkbox.
 * @param element object A jQuery checkbox object.
 * @return bool: TRUE on succes, FALSE on failure
 *
 */
function createAlternate(element)
{
    // check if the element has an id
    var elementId = $(element).attr('id');
    if (elementId == '')  {
	$(element).attr('id', generateId());
    }

    // class definitions for new checkbox button
    var defaultClass = 'styled_' + $(element).attr('type');
    var checkedClass = 'styled_' + $(element).attr('type') + '_checked';

	var tablecellparent = ' ';
	// find cell which is designed to be clicked
	if ($(element).attr('id') != '') {
		var findId = '#boxfor_'+$(element).attr('id');
		findId = validId(findId);
		tablecellparent = $(findId);
		if (tablecellparent.length == 0) {
			tablecellparent = ' ';
		}
	}
	if (typeof(tablecellparent) === 'string' ) {
		// find the first parent table cell
		tablecellparent = $(element).parents('td:first');
	}

    // create replacement element
    var altElement = $(document.createElement('input'));
    $(altElement).attr('type', 'button');
    $(altElement).attr('id', 'alt-' + validId($(element).attr('id')));
    $(altElement).addClass(defaultClass);

    // element to handle click to replace radiobutton
    var clickElement = $(altElement);
    // check for other clickable objects in this cell
    var inputs = $(tablecellparent).find('input,textarea,button,a,select,option');
    if (inputs.length === 1) {
        // use table as clickable element
        clickElement = $(tablecellparent);
    }
    // insert element alter the element it replaces
    $(altElement).insertAfter($(element));

    // set state for the replacement element
    if ($(element).attr('checked') == true) {
        $(altElement).addClass(checkedClass);
    }

    // bind click event
    $(clickElement).bind(
        'click',
        function(){
            if ($(element).attr('checked') != true) {
                if ($(element).attr('type') == 'radio') {
                    handleOnClickForRadiobuttons($(element).attr('name'));
                 }
                $(altElement).addClass(checkedClass);
                $(element).attr('checked',true);
            } else {
                if ($(element).attr('type') != 'radio') {
                    $(altElement).removeClass(checkedClass);
                    $(element).attr('checked',false);
                }
            }
	    // run onclick event for input element
	    $(element).trigger('onclick');
        }
    );
    // remove original element from view
    $(element).css('display','none');

    // indicate the element is clickable
//    $(clickElement).css('cursor','pointer');

    // get clickable element background-color
    var originalcolor = $(clickElement).css('background-color');
    var bgcolor = 'transparent';
    var row = $(clickElement).parents('tr');
    $.each(
		row,
		function() {
			if ($(this).css('background-color') != 'transparent' && bgcolor === 'transparent' || bgcolor === 'rgba(0, 0, 0, 0)') {
			bgcolor = $(this).css('background-color');
			}
		}
    );

    if (bgcolor === 'transparent' || bgcolor === 'rgba(0, 0, 0, 0)' || bgcolor === 'rgb(0, 0, 0)' ) {
		bgcolor = originalcolor;
    }
    var color = DarkerColor(bgcolor);

    // add hover class to clickable element
	$(clickElement).hover(
		function(){
			$(this).addClass('hover');
		$(this).css('background-color', color);
		},
		function() {
			$(this).removeClass('hover');
		$(this).css('background-color', originalcolor);
		}
	);

    // find the label for this element
    var labelFor = '' + escapeName($(element).attr('id'));
    var label=  $(document).find('[for='+ labelFor +']');
    if (label.length == 1) {
        // bind click action to label as well
        $(label).bind('click', function(){
            if ($(element).attr('checked') != true) {
                if ($(element).attr('type') === 'radio') {
                    handleOnClickForRadiobuttons($(element).attr('name'));
	                $(altElement).addClass(checkedClass);
                }
                $(element).attr('checked',true);
            } else {
                if ($(element).attr('type') != 'radio') {
                    $(element).attr('checked', false);
                } else {
                    $(altElement).removeClass(checkedClass);                
                }
            }
        });
    }
    return true;
}

/*
* function to reset all radiobuttons matching the given name.
*
* @param name string The name for the radiobuttons
 */
function handleOnClickForRadiobuttons(name)
{
    // find the original radiobuttons
    name = escapeName(name);
    var radiobuttons = $(document).find('[name=' + name + ']');
    $.each(
        radiobuttons,
        function() {
            var altId = '#alt-' + validId($(this).attr('id'));
            $(document).find(altId).removeClass('styled_radio_checked');
            // make sure all buttons are unset
            $(this).attr('checked', false);
        }
    );
}

//$(document).ready(function () {
	// no action for now. Actions are started from init in body
//});