//*****************************************************************************
// Copyright 2010 Flavours Interactive inc.
// All rights reserved.
//
// Flavours JavaScript Core.js
//
// brief : All the base function needed for Flavours AJAX applications
//		   These function uses MooTools extensively
//*****************************************************************************

window.addEvent('domready', function()
{
	// the entry point, executing javascript before this point
	// is not safe.

	flavours.init();
	//alert(window.location);
	
	
});


/****************************************************
 * Object flavours
 * brief : flavours specifies the build version
 * 		   and last build date.
 ****************************************************/
var flavours = {
	'version'  : "1.0.0" , 
	'modified' :"2010-08-13"
};

flavours._events_ = {}; 

flavours.init = function() {

	flavours.loadEvents(flavours.bindAllEvents);
	
}

flavours.loadEvents = function(onsuccess) {
	
	var mydate = new Date().valueOf();
	var loc = window.location;
	var myLocation = encodeURIComponent(loc);
	//alert(myLocation);
	var request = new Request({
		'url' : flavours_events_url + '&location=' + myLocation +'&time=' + mydate,
		'method' : "GET",
		'data' : "",
		'onSuccess' : function(response) {
			
			flavours._events_ = eval('(' + response + ')');
			onsuccess(flavours._events_);
		},
		'onFailure' : function(response) { 
		}
	
	});
	
	request.send();
}

flavours.bindAllEvents = function(events) {
	
	
	for(var name in events) 
	{
		// unserialize the value
		var eventObj = events[name];
		
		if(name.substr(0,6) == "_init_")
		{
			parseInitEvent(eventObj);
		} 
		else
		{
			var elementID = name;
			var element = document.id(elementID);
			
			// we cant find the element, skip the rest
			if (element == null) 
				continue;
			
			__parseUIEvent(element,eventObj);
		}
	}
}

flavours.bindEventsForElement = function(elementID, events) {
	
	if(events[elementID] == null) return;
	
	var eventObj = events[elementID];
	__parseUIEvent(document.id(elementID),eventObj);
		
}

flavours.alert = function(options){
	alert(options.message);
}

flavours.confirm = function(options){
	var accept = confirm(options.message);
	if(accept)
	{
		options.onAccept();
	}
}

/****************************************************
 * Object flavours.request 
 * brief : request does an XmlHttpRequest
 ****************************************************/
flavours.request = {};

flavours.request.sendRequest = function(options){
	var loc = window.location;
	var myLocation = encodeURIComponent(loc);

	var request = new Request({
		'url' : options.url + '&location=' + myLocation,
		'method' : options.method.toUpperCase(),
		'data' : options.data,
		'onSuccess' : function(response) { options.onSuccess(response); },
		'onFailure' : function(response) { options.onFailure(response); }
	
	});
	
	request.send();
};

/****************************************************
 * Object flavours.form 
 * brief : form related tasks
 ****************************************************/

flavours.form = {};

flavours.form.submit = function(options) {
	
	var form = document.getElementsByName(options.formName)[0];
	form.action = options.action;
	
	form.submit();
}

flavours.form.submitAsync = function(options) {
	
	var form = document.getElementsByName(options.formName)[0];
	
	var loc = window.location;
	var myLocation = encodeURIComponent(loc);
	//alert(myLocation);
	var data = getFormData(form);
	
	data = data + "&location=" + myLocation;
	
	var request = new Request({
		'url' : options.action,
		'method' : "POST",
		'data' : data,
		'onSuccess' : function(response) { options.onSuccess(response); },
		'onFailure' : function(response) { options.onFailure(response); }
	
	});
	
	request.send();
}

flavours.form.fillFormWithRequest = function(options) {
	
	var form = document.getElementsByName(options.formName)[0];
	
	var request = new Request({
		'url' : options.url,
		'method' : "GET",
		'data' : "",
		'onSuccess' : function(response) 
		{ 		
			setFormData(form,eval('(' + response + ')'));
			options.onSuccess(response); 

		},
		'onFailure' : function(response) { options.onFailure(response); }
	
	});
	
	request.send();
}

flavours.form.clear = function(options) {
	
	var form = document.getElementsByName(options.formName)[0];
	
	form.reset();
	
	if(form.id != null) form.id.value = 0;
	
	var inputFields = form.getElementsByTagName('input');
	for (i = 0; i < inputFields.length; i++)
	{
		inputFields[i].checked = false ;
		
		if(inputFields[i].type == 'hidden')
		{
			inputFields[i].value = '0';
		}
		
		// support for image selector
		// FIXME : I'm tired
		if(document.id('image' + inputFields[i].name) != null)
		{
			document.id('image' + inputFields[i].name).set('html','');
		}
	}
	
	var textareaFields = form.getElementsByTagName('textarea');  
	for (var i=0; i<textareaFields.length; i++) 
    {
		textareaFields[i].value = "";
		
		if(document.id(textareaFields[i]).getProperty('isMCE'))
		{
			tinymce.EditorManager.get(textareaFields[i].id).setContent("");
		}
	}
    
		
}
function setFormData(form,content) {
	
	var inputFields = form.getElementsByTagName('input');
	   
	// uncheck checkboxes
	for (var i=0; i<inputFields.length; i++) 
    {
		if (inputFields[i].type == "checkbox") {
			inputFields[i].checked = false;
		}
    }
    
	for(var fieldName in content)
	{
		for (var i=0; i<inputFields.length; i++) 
	    {
    		if(inputFields[i].type == "text" || inputFields[i].type == "password" || inputFields[i].type == "hidden") 
        	{
    			if(inputFields[i].name == fieldName)
    			{
    				inputFields[i].value = content[fieldName];  
    			
    				// support for image selector
    				// FIXME : I'm tired
	    			if(document.id('image' + inputFields[i].name) != null)
	    			{
	    				var image = inputFields[i].value.substr(inputFields[i].value.lastIndexOf('/')+1);
	    				var ext = image.substr(image.lastIndexOf('.')+1);
	    				var path = inputFields[i].value.substr(0,inputFields[i].value.lastIndexOf('/'));
	    				document.id('image' + inputFields[i].name).set('html','');
	    				if(ext == "jpg" || 
							ext == "jpeg" ||
							ext == "gif" || 
							ext == "png" || 
							ext == "bmp" )
						{
	    					
	    					var img = new Element('img');
							img.setProperty('src', path + '/_thumbs/' + image);
							img.setStyle('display','none');
							img.inject(document.id('image' + inputFields[i].name));
							
							(function(myImage){
								myImage.setProperty('width',myImage.width/2);
								myImage.setProperty('height',myImage.height/2);
								myImage.setStyle('display','block');
								}).delay(500,this,img);
						} 
						else if(ext == "pdf")
						{
							var img = new Element('div', {'class':'icon-128 document-pdf-64'});
							img.set('html', image);
							img.inject(document.id('image' + inputFields[i].name));
						}
						else if(ext == "flv" ||
								ext == "f4v" ||
								ext == "mp4" ||
								ext == "ogg" || 
								ext == "avi")
						{
							var img = new Element('div', {'class':'icon-64 film'});
							img.set('html', image);
							img.inject(document.id('image' + inputFields[i].name));
						}
	    				
						
	
						document.id('image' + inputFields[i].name).setStyle('display','block');
	    			}
    			}
        		
        	} 
    		else if (inputFields[i].type == "checkbox" && inputFields[i].name == fieldName) 
        	{
        		inputFields[i].checked = content[fieldName] != '0';        		
        	}
    	}
    }
	
	var textareaFields = form.getElementsByTagName('textarea');  
	for(var fieldName in content)
	{
		for (var i=0; i<textareaFields.length; i++) 
	    {
    		if(textareaFields[i].name == fieldName)
    		{
    			textareaFields[i].value = content[fieldName];
    			
    			if(document.id(textareaFields[i]).getProperty('isMCE'))
				{
    				tinymce.EditorManager.get(textareaFields[i].id).setContent(content[fieldName]);
				}
    		}
    	}
    }
    
    var selectFields = form.getElementsByTagName('select');
    for (var i=0; i<selectFields.length; i++) {
    	for(var fieldName in content)
    	{
    		if(selectFields[i].name == fieldName)
			{
    			var sel = selectFields[i];
    			for(var j = 0; j< sel.length ; j++)
				{
    				if(sel[j].value == content[fieldName])
    				{
    					sel.selectedIndex = j;
    					continue;
    				}
				}
			}
    	
    	}
    	
    }
}

function getFormData(obj) {
    var getstr = "";
        
    var inputFields = obj.getElementsByTagName('input');
    
    for (var i=0; i<inputFields.length; i++) {
    	
    	if(inputFields[i].type == "text" || inputFields[i].type == "password" || inputFields[i].type == "hidden") {
    		getstr += inputFields[i].name + "=" + encodeURIComponent(inputFields[i].value) + "&";
    	} else if (inputFields[i].type == "checkbox") {
    		if(inputFields[i].checked)
        	{
        		getstr += inputFields[i].name + "=" + encodeURI(inputFields[i].value) + "&";
        	}
    	}
    }
    
    var textareaFields = obj.getElementsByTagName('textarea');
    
    for (var i=0; i<textareaFields.length; i++) 
    {
    	if(document.id(textareaFields[i]).getProperty('isMCE'))
		{
    		getstr += textareaFields[i].name + "=" + encodeURIComponent(tinymce.EditorManager.get(textareaFields[i].id).getContent()) + "&";	
			//tinyMCE.get(textareaFields[i].name).setContent(content[fieldName]);
		}
    	else
    	{
    		getstr += textareaFields[i].name + "=" + encodeURIComponent(textareaFields[i].value) + "&";	
    	}
	}
    
    var selectFields = obj.getElementsByTagName('select');
    for (var i=0; i < selectFields.length; i++) 
    {
    	var sel = selectFields[i];
    	
    	var resultString = '';
    	var indices = retrieveSelectedElementIndices(sel);
    	for(var j = 0; j < indices.length; j++)
    	{
    		resultString += indices[j];
 
    		if(j != (indices.length-1))
    			resultString += ',';
    	}
    
    	getstr += sel.name + "=" + encodeURI(resultString) + "&";

    }
    
    return getstr;
}

var retrieveSelectedElementIndices = function(element)
{
	var domElement = document.id(element);
	
	var selected = new Array(); 
	//alert(domElement.options.length);
	for (var i = 0; i < domElement.options.length; i++) 
	{
		if (domElement.options[ i ].selected) 
			selected.push(domElement.options[ i ].value);
	}
	
	return selected;
}

var parseInitEvent = function(eventObj) 
{
	if(typeOf(eventObj) == 'string')
	{
		eval(eventObj);
	}
	else
	{
		var funcBody = __parseFunctionRecursive("",eventObj);
		// lets execute the code right away
		eval(funcBody);
	}
}

var __executeEventCallBack = function(event, codeToExecute)
{
	eval(codeToExecute);
}

var __parseUIEvent = function(element, eventObj) 
{
	// eventObj is an object, contains keys like click, dblclick...etc..
	for(var event in eventObj)
	{
		if(typeOf(eventObj[event]) == 'string')
		{
			// The event content is a string
			//alert(eventObj[event]);
			element.addEvent(event, function(evt){__executeEventCallBack(evt, eventObj[event]);});
		}
		else
		{
			// The event content is an object
			var funcBody = __parseFunctionRecursive("",eventObj[event]);
	
			//alert(funcBody);
			
			element.addEvent(event, (function (mylocalvariable) { 
		        return function(){
		        	eval(mylocalvariable);
		        	
		        };
		    })(funcBody) );
		}
	}
}

var __parseFunctionRecursive = function(ioStr, iFunc) {
	
	// iFunc is a set of functions
	iFunc.each(function(item)
	{
		var funcObj = item;
		for(var funcName in funcObj)
		{
			var func = funcObj[funcName];
			ioStr += funcName + '({';
			
			// all the functions take an object as input args
			// parse parameters
			for(var paramName in func)
			{
				
				ioStr += paramName + " : ";
				
				if($type(func[paramName]) == 'string')
				{	
					if(func[paramName].substr(0,1) =="{")
					{
						// dont quote this one
						ioStr += func[paramName].substr(1,func[paramName].length -2) + ',';
					}
					else
					{
						ioStr += '"' + func[paramName] + '",';
					}
					
				}
				else if ($type(func[paramName]) == 'array'){
					ioStr += "function(response){";
					//alert(funcName + " " + paramName +  " type: " + $type(func[paramName]));
					var sub = __parseFunctionRecursive("",func[paramName]);
					
					ioStr += sub + "},";
					
					
				}
				
			
			}
			
			ioStr = ioStr.substr(0,ioStr.length-1);
			ioStr += "});";
			
			
				
		}
		
		
	});
	
	return ioStr;
	
}
/*
 * Convert a 32-bit number to a hex string with ls-byte first
 */
var hex_chr = "0123456789abcdef";
function rhex(num)
{
  str = "";
  for(j = 0; j <= 3; j++)
    str += hex_chr.charAt((num >> (j * 8 + 4)) & 0x0F) +
           hex_chr.charAt((num >> (j * 8)) & 0x0F);
  return str;
}

/*
 * Convert a string to a sequence of 16-word blocks, stored as an array.
 * Append padding bits and the length, as described in the MD5 standard.
 */
function str2blks_MD5(str)
{
  nblk = ((str.length + 8) >> 6) + 1;
  blks = new Array(nblk * 16);
  for(i = 0; i < nblk * 16; i++) blks[i] = 0;
  for(i = 0; i < str.length; i++)
    blks[i >> 2] |= str.charCodeAt(i) << ((i % 4) * 8);
  blks[i >> 2] |= 0x80 << ((i % 4) * 8);
  blks[nblk * 16 - 2] = str.length * 8;
  return blks;
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally 
 * to work around bugs in some JS interpreters.
 */
function add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left
 */
function rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * These functions implement the basic operation for each round of the
 * algorithm.
 */
function cmn(q, a, b, x, s, t)
{
  return add(rol(add(add(a, q), add(x, t)), s), b);
}
function ff(a, b, c, d, x, s, t)
{
  return cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function gg(a, b, c, d, x, s, t)
{
  return cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function hh(a, b, c, d, x, s, t)
{
  return cmn(b ^ c ^ d, a, b, x, s, t);
}
function ii(a, b, c, d, x, s, t)
{
  return cmn(c ^ (b | (~d)), a, b, x, s, t);
}

/*
 * Take a string and return the hex representation of its MD5.
 */
function calcMD5(str)
{
  x = str2blks_MD5(str);
  a =  1732584193;
  b = -271733879;
  c = -1732584194;
  d =  271733878;

  for(i = 0; i < x.length; i += 16)
  {
    olda = a;
    oldb = b;
    oldc = c;
    oldd = d;

    a = ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = ff(c, d, a, b, x[i+10], 17, -42063);
    b = ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = ff(d, a, b, c, x[i+13], 12, -40341101);
    c = ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = ff(b, c, d, a, x[i+15], 22,  1236535329);    

    a = gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = gg(c, d, a, b, x[i+11], 14,  643717713);
    b = gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = gg(c, d, a, b, x[i+15], 14, -660478335);
    b = gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = gg(b, c, d, a, x[i+12], 20, -1926607734);
    
    a = hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = hh(b, c, d, a, x[i+14], 23, -35309556);
    a = hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = hh(d, a, b, c, x[i+12], 11, -421815835);
    c = hh(c, d, a, b, x[i+15], 16,  530742520);
    b = hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = ii(c, d, a, b, x[i+10], 15, -1051523);
    b = ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = ii(d, a, b, c, x[i+15], 10, -30611744);
    c = ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = add(a, olda);
    b = add(b, oldb);
    c = add(c, oldc);
    d = add(d, oldd);
  }
  return rhex(a) + rhex(b) + rhex(c) + rhex(d);
}

