var activetab = 0;
var activenav = 0;
var stabs = new Array('30', '31', '32', '33', '34', '35', '36', '37','38','39','40');
var timer;

//document.observe("dom:loaded", function() { } );
Event.observe(window, 'resize', function(){	setSize(); });
Event.observe(window, 'scroll', function(){	setSize(); });

function gup( name )
{
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results == null )
    return "";
  else
    return results[1];
}

var frontPage = null;
var fp = parseInt(gup('t'));
if(fp) {
	frontPage = fp;
}

function startAnim() {
	shiftzoom.add($('preview'),{buttons:false, overview:false, nozoom:false, lowres:'wp-content/themes/yda_v2/img/background_v3_small.jpg'});
	ydaZoom(frontPage);
}

function ydaZoom(tab) {
	if (tab == activetab) return false;
	if (tab == null) var tab = 0;
	setSize();
	hideTab(activetab);

	$tabcontent = $('tab'+tab+'content');
	if ($tabcontent != null && !$tabcontent.hasClassName('loaded') && tab_id[tab]) {
		new Ajax.Updater('tab'+tab+'content', '?page_id='+tab_id[tab]); // preload content of the tab
	}
	switch (tab) {
		case 0: shiftzoom.kenburns($('preview'),[30,34,	100,3,10,100,'showTab',tab]); break;
		case 1: shiftzoom.kenburns($('preview'),[0,0,	100,3,10,100,'showTab',tab]); break;
		case 2: shiftzoom.kenburns($('preview'),[33,0,	100,3,10,100,'showTab',tab]); break;
		case 3: shiftzoom.kenburns($('preview'),[67,0,	100,3,10,100,'showTab',tab]); break;
		case 4: shiftzoom.kenburns($('preview'),[0,26,	100,3,10,100,'showTab',tab]); break;
		case 5: shiftzoom.kenburns($('preview'),[68,58,	100,3,10,100,'showTab',tab]); break;
		case 7: shiftzoom.kenburns($('preview'),[0,59,	100,3,10,100,'showTab',tab]); break;
		case 8: shiftzoom.kenburns($('preview'),[32.5,58,	100,3,10,100,'showTab',tab]); break;

		/*case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 39:
		case 37: shiftzoom.kenburns($('preview'),[69,27,	100,3,10,100,'showTab',tab]); break;*/

		default:
			var br = false;
			for(var i=0; i<stabs.length;i++) {
				if(stabs[i] == tab) {
					 shiftzoom.kenburns($('preview'),[69,27, 100,3,10,100,'showTab',tab]);
					 br = true;
					 break;
				}
			}
			if(!br)
				shiftzoom.kenburns($('preview'),[0,0, 100,3,10,100,'showTab',1]);
		break;
	}
}

function hideTab(tab) {
	if (stabs.inArray(tab)) {
		$('tab'+tab).setStyle({display: 'none'});
		var temptab = tab; tab = 3;
		$('nav'+tab).removeClassName('selected');
		tab = temptab;
	} else {
		if (tab > 0) {
			$('tab'+activetab).setStyle({display: 'none'});
			$('nav'+activetab).removeClassName('selected');
		}
	}
}

function showTab(tab,data) {
	if (tab > 0) {
		$('tab'+tab).setStyle({display: 'block'});
		$('logo').setStyle({display: 'block'});
		$('logo2').setStyle({display: 'block'});
		clearTimeout(timer);
	} else {
		timer = setTimeout('ydaZoom(1)', 3000);
	}

	if (stabs.inArray(tab)) {
		$tabcontent = $('tab'+tab+'content');
		if ($tabcontent != null && !$tabcontent.hasClassName('loaded')) {
			
			if (tab == 31) { // preload next tab
				new Ajax.Updater('tab'+tab+'content', '?page_id='+tab_id[tab], {asynchronous: false});
				new Ajax.Updater('tab32content', '?page_id='+tab_id[32], {asynchronous: false});
			} else {
				new Ajax.Updater('tab'+tab+'content', '?page_id='+tab_id[tab], {asynchronous: false});
			}
		}
		var tabtemp = tab; tab = 3;
		$('nav'+tab).addClassName('selected');
		tab = tabtemp;
		activetab = tab;
	} else {
		$('nav'+tab).addClassName('selected');
		activetab = tab;
	}
	if (tab > 0) $('tab'+tab+'content').addClassName('loaded');

	tabspecials(tab,data);
}

mydirectors = new Array();
function tabspecials(tab,data) {
	tab = parseInt(tab);
	switch (tab) {
		case 1:
			$ne = $('news_email');
			$ne.observe('focus', function(event) { if (this.value == 'Type in your email address') this.value=''; });
			$ne.observe('blur', function(event) { if (this.value == '') this.value='Type in your email address'; });
			break;
		case 8:
				var vh = document.viewport.getHeight();
				var vw = document.viewport.getWidth();
				var hh = $('header').getHeight();
				var h = vh - hh;
				var tt = $('tab'+tab+'content').getStyle('top').replace(/px/, "");
				var th = h - tt;
				$('tab'+tab+'content').setStyle({height: th+'px'});

			break;
		case 30:
			if(isLogged()) {
				hideTab(tab); showTab(31);
				//new Ajax.Updater('tab'+tab+'content', '?page_id='+tab_id[31], {asynchronous: false});
			} else {
				new Ajax.Updater('tab'+tab+'content', '?page_id='+tab_id[30], {asynchronous: false}); // refresh
			}
			break;
		case 31:
			if(!isLogged()) { hideTab(tab); showTab(30); break; }

			var url = 'wp-content/themes/yda_v2/directorlist.php?';
			var status = false;

			var curdirector = $('director').value;
			new Ajax.Request(url, {
				asynchronous: false,
				onSuccess: function(response) {
					for(var i=0; i < $('director').length; i++) {
						$('director').options[i] = null;
					}

					try {
						var json_obj = response.responseText.evalJSON();
						var i = 0;
						for(var i=0;i<json_obj.length;i++) {
							var d = json_obj[i];
							mydirectors[d.id] = d;
							$('director').options[i] = new Option(d.name,d.id);
							if(curdirector == d.id) {
								$('director').options[i].selected = true;
							}
						}
					}
					catch(e) {
						alert('Error fetching tje list of directors.. Please try again.');
					}
				}
			});

			break;
		case 32:
			if(!isLogged()) { hideTab(tab); showTab(30); break; }
			if($('director').value > 0) {
				var d = mydirectors[$('director').value];
				$('name').value = d.name;
				$('date_of_birth_dd').value = d.date_of_birth_dd;
				$('date_of_birth_mm').value = d.date_of_birth_mm;
				$('date_of_birth_yyyy').value = d.date_of_birth_yyyy;
				$('nationality').value = d.nationality;
				$('email').value = d.email;
				$('phone').value = d.phone;
				$('address').value = d.address;
				$('education').value = d.education;
				$('jobs').value = d.jobs;
				$('profile').value = d.profile;
				wordCount($('profile'), 200);
			}

			break;
		case 33:
			if(!isLogged()) { hideTab(tab); showTab(30); break; }
			el1 = $('enter_your_film_1').select('input','select','textarea')
			el2 = $('enter_your_film_2').select('input','select','textarea');
			el1.invoke('updateFormSummary');
			el2.invoke('updateFormSummary');
			break;
		case 34:
			if(!isLogged()) { hideTab(tab); showTab(30); break; }
			break;
		case 35:
			if(!isLogged()) { hideTab(tab); showTab(30); break; }
			$('tab35content').removeClassName('loaded');

			clearInterval(progInterval);
			progInterval = null;
   			document.getElementById('upload_image_input').style.display = 'block';
   			document.getElementById('pb_outer_image').style.display = 'none';

   			/*var curdate = new Date();
   			var r = Math.random()+curdate;
   			$('progress_key_image').value = hex_md5(r)+Math.random();*/

			$('upload_image').onsubmit = function() {
				startProgress($('progress_key_image').value,'image');
				$('upload_image').target = 'upload_image_target';
			}
			break;
		case 36:
			if(!isLogged()) { hideTab(tab); showTab(30); break; }
			$('tab36content').removeClassName('loaded');

			clearInterval(progInterval);
			progInterval = null;
   			document.getElementById('upload_video_input').style.display = 'block';
   			document.getElementById('pb_outer_video').style.display = 'none';

   			/*var curdate = new Date();
   			var r = Math.random()+curdate;
   			$('progress_key_video').value = hex_md5(r)+Math.random();*/

			$('upload_video').onsubmit = function() {
				startProgress($('progress_key_video').value,'video');
				$('upload_video').target = 'upload_video_target';
			}
			break;
		case 37:
			if(!isLogged()) { hideTab(tab); showTab(30); break; }
			clearInterval(progInterval);
			progInterval = null;

   			/*var curdate = new Date();
   			var r = Math.random()+curdate;
   			$('progress_key_image').value = hex_md5(r)+Math.random();*/

   			/*var curdate = new Date();
   			var r = Math.random()+curdate;
   			$('progress_key_video').value = hex_md5(r)+Math.random();*/

			saveFormData();
			$('sum_video').innerHTML = data.file_name;
			$('sum_videsize').innerHTML = Math.round(data.size/1024)+' MB';
			break;
		default:
	}
}

var formdata = new Array();

function saveFormData() {
	f1 = $('enter_your_film_1').select('input','select','textarea','checkbox','radio')
	f2 = $('enter_your_film_2').select('input','select','textarea','checkbox','radio');
	f3 = $('upload_image').select('input');
	f4 = $('upload_video').select('input');

	f1.invoke('updateFormData');
	f2.invoke('updateFormData');
	f3.invoke('updateFormData');
	f4.invoke('updateFormData');

	if (true) {
		var url = 'wp-content/themes/yda_v2/saveformdata.php?';
		var status = false;

		new Ajax.Request(url, {
			asynchronous: false,
			//parameters: Form.serialize($('formdata')),
			parameters: formdata,
			onSuccess: function(response) {
				try {
					var json_obj = response.responseText.evalJSON();
					if (json_obj['saved'] == 1 && parseInt(json_obj['id']) > 0) {
						status = true;
						if(json_obj['payment_required']) {
							$('finish_button').hide();
							$('payment').show();
							$('paypal_firstname').value = json_obj['firstname'];
							$('paypal_lastname').value = json_obj['lastname'];
							$('paypal_custom').value = parseInt(json_obj['id']);
							$('paypal_item_name').value = json_obj['title'];
						}
						else {
							$('payment').hide();
							$('finish_button').show();
						}
					}
					else {
						throw "failed";
					}
				}
				catch(e) {
					status = false;
					alert("Unknown error on form. Please, confirm your data is correct and try again.");
				}
			},
			onFailure: function() {
				alert('Sign up failed! Please try again..');
				status = false;
			}
		});
		//alert("status: "+status);
		return status;
	}
}

var types = new Array('text','checkbox','radio','select-one','textarea');

Element.addMethods( {
	updateFormData: function(el){
		//ne = el.next();
		es = el.name;

		if (/*$(es) != null && */types.inArray(el.type)) {

			var val = null;
			if ($(el).type && $(el).type.toLowerCase() == 'radio') {
				val = $RF(el);
			} else if ($(el).type && $(el).type.toLowerCase() == 'checkbox') {
				($(el).checked) ? val = el.value : null;
			} else {
				val = el.value;
			}

			//console.log(el.name +' - '+ el.type +' - '+ el.value);
			formdata[el.name] = val;
		}
	},

	updateFormSummary: function(el){
		//ne = el.next();
		es = 'sum_'+el.name;
		//alert(el.name +' - '+ el.type +' - '+ el.value);
		if ($(es) != null) {
			if ($(el).type && $(el).type.toLowerCase() == 'radio') {
				var test = $RF(el);
				$(es).update(test);
			} else if ($(el).type && $(el).type.toLowerCase() == 'checkbox') {
				$(es).update(($(el).checked) ? 'Yes' : 'No');
			} else if ($(el).type && $(el).type.toLowerCase() == 'select-one') {
				$(es).update($(el)[$(el).selectedIndex].text);
			} else {
				$(es).update(el.value);
			}
		}
	}
});

var pros = 0;
var fakeProgress = false;
function getProgress(uid,type) {

	//FAKE PROGRESS
	if(fakeProgress == type) {
    	document.getElementById('pb_inner_'+type).style.width = pros + '%';
		if(pros >= 100) pros = 0;
		pros++;
	}
	else {
		//REAL PROGRESS
		new Ajax.Request('wp-content/themes/yda_v2/apc.php?uid=' + uid, {
	  		method: 'get',
	  		onSuccess: function(transport) {
		    	var progress = parseInt(transport.responseText);
		    	if(progress == 'NaN') progress = 0;
	    	    document.getElementById('pb_inner_'+type).style.width = progress + '%';
	        	document.getElementById('pb_inner_'+type).innerHTML = '&nbsp;&nbsp;&nbsp;' + progress + '%';
	        	if(pros >= 100) pros = 0;
	        	if(progress < 100) {
	           		//setTimeout('getProgress("' + uid + '","'+type+'")', 10);
	        	}
	        	else {
					clearInterval(progInterval);
					progInterval = null;
	           		document.getElementById('pb_inner_'+type).innerHTML = '&nbsp;&nbsp;&nbsp;Upload Complete! Converting, please wait...';
	           		pros = 0;
	           		fakeProgress = type;
	           		setTimeout('startProgressInterval("' + uid + '","'+type+'",100)', 1000);
	        	}
			}
		});
	}
}

function startProgressInterval(uid,type,interval) {
	progInterval = setInterval('getProgress("' + uid + '","'+type+'")',interval);
}

var progInterval = null;
function startProgress(uid,type) {
	pros = 0;
   document.getElementById('upload_'+type+'_input').style.display = 'none';
   document.getElementById('pb_outer_'+type).style.display = 'block';

	clearInterval(progInterval);
	progInterval = null;

   //FAKE PROGRESS
   //progInterval = setInterval('getProgress("' + uid + '","'+type+'")',10);
   //document.getElementById('pb_inner_'+type).innerHTML = '&nbsp;&nbsp;&nbsp;Uploading, please wait...';
   //fakeProgress = type;

  //REAL PROGRESS
  fakeProgress = false;
  setTimeout('startProgressInterval("' + uid + '","'+type+'",500)', 1000);
}

function uploadDone(name) {
	clearInterval(progInterval);
	progInterval = null;

	var ret = frames['upload_'+name+'_target'].document.getElementsByTagName("body")[0].innerHTML;
	var data = eval("("+ret+")");
	if (data.success) {
		//$("image_details").update('<img src="wp-content/uploads/thumbnails/' + data.file_name + '" alt="" /><br />Size: ' + data.size + ' KB');
		hideTab(activetab);
		formdata[name] = data.file_name;
		if (name == 'image') showTab(36);
		else if (name == 'video') showTab(37,data);
	} else if(data.failure) {
		alert("Upload Failed: " + data.failure);
   		document.getElementById('upload_'+name+'_input').style.display = 'block';
   		document.getElementById('pb_outer_'+name).style.display = 'none';
	}
}

function checkForm(tab) {
	var tab = parseInt(tab);
	var errors = new Array();

	var $tabcontent = $('tab'+tab+'content').select('input','select','textarea');
	errors = $tabcontent.invoke('checkField');
/*
	switch (tab) {
		case 30:
			var $tabcontent = $('tab'+tab+'content').select('input','select','textarea');
			errors = $tabcontent.invoke('checkField');
			break;

		default:
	}
*/
	if (errors.inArray(false))
		return false
	else
		return true;
}


Element.addMethods( {
	checkField: function(el){
		//alert(el.name +' '+ el.type +' '+ el.value);
		switch (el.name) {
			case 'company_name':
			case 'street':
			case 'postal':
			case 'city':
			case 'country':
			case 'phone':
			case 'firstname':
			case 'lastname':
			case 'email':
			case 'password1':
			case 'password2':

			case 'producer':
			case 'director_of_photography':
			case 'art_director':
			case 'agency_producer':
			case 'creative_director':
			case 'product':
			case 'synopsis':

			case 'name':
			case 'phone':
			case 'address':
			case 'education':
			case 'jobs':
			case 'profile':
				// generic :: if [field] is empty
				if (el.value == '') { $(el.name).addClassName('error'); return false; }
				else $(el.name).removeClassName('error');

				// email validity
				if(el.name == "email" && !el.value.match(/^\w(\.?\w)+@\w(\.?[-\w])+\.[a-z]{2}(?:\.[a-z]{2})?|[a-z]{2}\.[a-z]{2}/) ){
					alert('Your email is not valid.');
					$(el.name).addClassName('error');
					return false;
				}

				// if passwords is too shoty
				if (el.name == "password1" && el.value.length < 4) { alert('Your password is too short. (4 characters min.)'); return false; }

				// if passwords dont match
				if (el.name == "password2" && el.value != $('password1').value) {
					$(el.name).addClassName('error');
					alert('Your confirm password did not match. Please try again..');
					return false; }
				else $(el.name).removeClassName('error');
				break;

			case 'film_length':
				if (el.value == '') { $(el.name).addClassName('error'); return false; }
				if (!IsNumeric(el.value)) { $(el.name).addClassName('error'); alert("Please give the film length in seconds."); return false; }
				else $(el.name).removeClassName('error');
				break;

			case 'agree':
				// if [field] is checked
				if (!el.checked) { $(el.name).addClassName('error'); alert("You have to agree the terms before you can continue.."); return false; }
				else $(el.name).removeClassName('error');
				break;
			default:
				//alert('Field error!');
				break;
		}

		return true;
	}
});


function sendForm (formid) {
	var url = 'wp-content/themes/yda_v2/signup.php?';
	var status = false;

	new Ajax.Request(url, {
		asynchronous: false,
		parameters: Form.serialize($(formid)),
		onSuccess: function(response) {

			try {
				var json_obj = response.responseText.evalJSON();

				if (json_obj['saved'] == 1) {
					status = true;
				}
				else {
					status = false;
					alert('Error: "'+json_obj[0]+'"');
				}
			}
			catch(e) {
				alert("Unknown error on form. Please, confirm your data is correct and try again.");
			}
		},
		onFailure: function() {
			alert('Sign up failed! Please try again..');
			status = false;
		}
	});
	//alert("status: "+status);
	return status;
}

function isLogged () {
	var url = 'wp-content/themes/yda_v2/islogged.php?';
	var status = false;

	new Ajax.Request(url, {
		asynchronous: false,
		onSuccess: function(response) {
			try {
				var json_obj = response.responseText.evalJSON();

				if (json_obj['login'] == 1) {
					if($('notloggedin')) {
						$('notloggedin').remove();
					}
					if($('signup')) {
						$('signup').remove();
					}
					status = true;
				}
			}
			catch(e) {

			}
		},
		onFailure: function() {
			alert('Login failed! Please try again..');
			status = false;
		}
	});
	return status;
}

function logout () {
	var url = 'wp-content/themes/yda_v2/logout.php?';
	var status = false;

	new Ajax.Request(url, {
		asynchronous: false,
		onSuccess: function(response) {
			try {
				var json_obj = response.responseText.evalJSON();
				if (json_obj['logout'] == 1) {
					status = true;
				}
			}
			catch(e) {}
		},
		onFailure: function() {
			alert('Logout failed! Please try again..');
		}
	});
	return status;
}


function logIn (formid) {
	var url = 'wp-content/themes/yda_v2/login.php?';
	var status = false;

	new Ajax.Request(url, {
		asynchronous: false,
		parameters: Form.serialize($(formid)),
		onSuccess: function(response) {
			try {
				var json_obj = response.responseText.evalJSON();

				if (json_obj['login'] == 1) {
					status = true;
				}
				else {
					status = false;
					alert(json_obj['error']);
				}
			}
			catch(e) {
				alert("Unknown error");
			}
		},
		onFailure: function() {
			alert('Login failed! Please try again..');
			status = false;
		}
	});
	return status;
}


function upload() {
	$('file_upload_form').onsubmit = function() {
		$('file_upload_form').target = 'upload_target'; //'upload_target' is the name of the iframe
	}
}

// tarkastaa onko teksti pelkkia numeroita
function IsNumeric(sText) {
	var ValidChars = "0123456789";
	var IsNumber = true;
	var Char;

	for (i = 0; i < sText.length && IsNumber == true; i++) {
		Char = sText.charAt(i);
		if (ValidChars.indexOf(Char) == -1) {
			IsNumber = false;
		}
	}
	return IsNumber;
}

var char_limit = 0;
var char_limit_alert = true;

function wordCount(textarea, limit) {
	var char_cnt = textarea.value.length;
	var word_cnt = textarea.value.split(/\s/);
	word_cnt = word_cnt.length;

	if (word_cnt >= limit) {
		if (char_limit == 0) char_limit = char_cnt;
		textarea.value = textarea.value.substring(0, char_limit);
		if (char_limit_alert) {
			alert('You have reached the '+limit+' word limit.');
			char_limit_alert = false;
		}
	} else {
		$('counter').update(limit - word_cnt);
	}
}

/**
* Returns the value of the selected radio button in the radio group, null if
* none are selected, and false if the button group doesn't exist
*
* @param {radio Object} or {radio id} el
* OR
* @param {form Object} or {form id} el
* @param {radio group name} radioGroup
*/
function $RF(el, radioGroup) {
	if($(el).type && $(el).type.toLowerCase() == 'radio') {
		var radioGroup = $(el).name;
		var el = $(el).form;
	} else if ($(el).tagName.toLowerCase() != 'form') {
		return false;
	}

	var checked = $(el).getInputs('radio', radioGroup).find(
		function(re) {return re.checked;}
	);
	return (checked) ? $F(checked) : null;
}

function setSize() {
	//$('nav'+activetab).addClassName('selected');

	var vh = document.viewport.getHeight();
	var vw = document.viewport.getWidth();
	var hh = $('header').getHeight();
	var h = vh - hh;

	$('content_wrap').setStyle({height: h+'px'});
	$('content').setStyle({height: h+'px'});

	// derprecated
	//var tt = $('tab'+activetab+'content').getStyle('top').replace(/px/, "");
	//var th = h - tt;
	//$('tab'+activetab+'content').setStyle({height: th+'px'});

	$('wrapper').setStyle({height: vh+'px', width: '100%'});
}

var activeShotlist = "winners-frontpage";
var activelink_nav = "link2008-nec";

function shortlistChange(id, activelink) {
	var $id = $(id);
	$(activeShotlist).setStyle({display: 'none'});
	$id.setStyle({display: 'block'});
	activeShotlist = id;

	$(activelink_nav).removeClassName('selected');
	$(activelink).addClassName('selected');
	activelink_nav = activelink;
}

var activelinkyear = "list-2008";
var activelinkyear_nav = "link2008";

function shortlistChangeYear(id, activeyear) {
	var $id = $(id);
	$(activelinkyear).setStyle({display: 'none'});
	$id.setStyle({display: 'block'});
	activelinkyear = id;

	$(activelinkyear_nav).removeClassName('selected');
	$(activeyear).addClassName('selected');
	activelinkyear_nav = activeyear;
}


function oc(a) {
	var o = {};
	for(var i=0; i<a.length; i++) {
		o[a[i]]='';
	}
	return o;
}

Array.prototype.inArray = function (value) {
	// Returns true if the passed value is found in the array. Returns false if it is not.
	var i;
	for (i=0; i<this.length; i++) {
		// Matches identical (===), not just similar (==).
		if (this[i] == value) {
			return true;
		}
	}
	return false;
};

function newsletter (formid) {
	var url = 'wp-content/themes/yda_v2/newsletter.php?';
	var status = false;

	new Ajax.Request(url, {
		asynchronous: false,
		parameters: Form.serialize($(formid)),
		onSuccess: function(response) {
			try {
				var json_obj = response.responseText.evalJSON();

				if (json_obj['saved'] == 1) {
					$('newsletter').update('<p>You have been signed up for the newsletter..</p>');
					status = true;
				}
				else {
					status = false;
					alert('Error: "'+json_obj[0]+'"');
				}
			}
			catch(e) {
				alert("Unknown error");
			}
		},
		onFailure: function() {
			alert('Sign up failed! Please try again..');
			status = false;
		}
	});
	return status;
}


var Cookie = {
  data: {},
  options: {expires: 1, domain: "", path: "", secure: false},

init: function(options, data) {
  Cookie.options = Object.extend(Cookie.options, options || {});

  var payload = Cookie.retrieve();
        if(payload) {
            Cookie.data = payload.evalJSON();
        }
        else {
            Cookie.data = data || {};
        }
        Cookie.store();
    },
    getData: function(key) {
        return Cookie.data[key];
    },
    setData: function(key, value) {
        Cookie.data[key] = value;
        Cookie.store();
    },
    removeData: function(key) {
        delete Cookie.data[key];
        Cookie.store();
    },
    retrieve: function() {
        var start = document.cookie.indexOf(Cookie.options.name + "=");

        if(start == -1) {
            return null;
        }
        if(Cookie.options.name != document.cookie.substr(start, Cookie.options.name.length)) {
            return null;
        }

        var len = start + Cookie.options.name.length + 1;
        var end = document.cookie.indexOf(';', len);

        if(end == -1) {
            end = document.cookie.length;
        }
        return unescape(document.cookie.substring(len, end));
    },
    store: function() {
        var expires = '';

        if (Cookie.options.expires) {
            var today = new Date();
            expires = Cookie.options.expires * 86400000;
            expires = ';expires=' + new Date(today.getTime() + expires);
        }

        document.cookie = Cookie.options.name + '=' + escape(Object.toJSON(Cookie.data)) + Cookie.getOptions() + expires;
    },
    erase: function() {
        document.cookie = Cookie.options.name + '=' + Cookie.getOptions() + ';expires=Thu, 01-Jan-1970 00:00:01 GMT';
    },
    getOptions: function() {
        return (Cookie.options.path ? ';path=' + Cookie.options.path : '') + (Cookie.options.domain ? ';domain=' + Cookie.options.domain : '') + (Cookie.options.secure ? ';secure' : '');
    }
};


/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;   /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = "";  /* base-64 pad character. "=" for strict RFC compliance   */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_md5(s)    { return rstr2hex(rstr_md5(str2rstr_utf8(s))); }
function b64_md5(s)    { return rstr2b64(rstr_md5(str2rstr_utf8(s))); }
function any_md5(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); }
function hex_hmac_md5(k, d)
  { return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
function b64_hmac_md5(k, d)
  { return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
function any_hmac_md5(k, d, e)
  { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); }

/*
 * Perform a simple self-test to see if the VM is working
 */
function md5_vm_test()
{
  return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72";
}

/*
 * Calculate the MD5 of a raw string
 */
function rstr_md5(s)
{
  return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
}

/*
 * Calculate the HMAC-MD5, of a key and some data (raw strings)
 */
function rstr_hmac_md5(key, data)
{
  var bkey = rstr2binl(key);
  if(bkey.length > 16) bkey = binl_md5(bkey, key.length * 8);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
  return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
}

/*
 * Convert a raw string to a hex string
 */
function rstr2hex(input)
{
  try { hexcase } catch(e) { hexcase=0; }
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var output = "";
  var x;
  for(var i = 0; i < input.length; i++)
  {
    x = input.charCodeAt(i);
    output += hex_tab.charAt((x >>> 4) & 0x0F)
           +  hex_tab.charAt( x        & 0x0F);
  }
  return output;
}

/*
 * Convert a raw string to a base-64 string
 */
function rstr2b64(input)
{
  try { b64pad } catch(e) { b64pad=''; }
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var output = "";
  var len = input.length;
  for(var i = 0; i < len; i += 3)
  {
    var triplet = (input.charCodeAt(i) << 16)
                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
    }
  }
  return output;
}

/*
 * Convert a raw string to an arbitrary string encoding
 */
function rstr2any(input, encoding)
{
  var divisor = encoding.length;
  var i, j, q, x, quotient;

  /* Convert to an array of 16-bit big-endian values, forming the dividend */
  var dividend = Array(Math.ceil(input.length / 2));
  for(i = 0; i < dividend.length; i++)
  {
    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
  }

  /*
   * Repeatedly perform a long division. The binary array forms the dividend,
   * the length of the encoding is the divisor. Once computed, the quotient
   * forms the dividend for the next step. All remainders are stored for later
   * use.
   */
  var full_length = Math.ceil(input.length * 8 /
                                    (Math.log(encoding.length) / Math.log(2)));
  var remainders = Array(full_length);
  for(j = 0; j < full_length; j++)
  {
    quotient = Array();
    x = 0;
    for(i = 0; i < dividend.length; i++)
    {
      x = (x << 16) + dividend[i];
      q = Math.floor(x / divisor);
      x -= q * divisor;
      if(quotient.length > 0 || q > 0)
        quotient[quotient.length] = q;
    }
    remainders[j] = x;
    dividend = quotient;
  }

  /* Convert the remainders to the output string */
  var output = "";
  for(i = remainders.length - 1; i >= 0; i--)
    output += encoding.charAt(remainders[i]);

  return output;
}

/*
 * Encode a string as utf-8.
 * For efficiency, this assumes the input is valid utf-16.
 */
function str2rstr_utf8(input)
{
  var output = "";
  var i = -1;
  var x, y;

  while(++i < input.length)
  {
    /* Decode utf-16 surrogate pairs */
    x = input.charCodeAt(i);
    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
    {
      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
      i++;
    }

    /* Encode output as utf-8 */
    if(x <= 0x7F)
      output += String.fromCharCode(x);
    else if(x <= 0x7FF)
      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
                                    0x80 | ( x         & 0x3F));
    else if(x <= 0xFFFF)
      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
                                    0x80 | ((x >>> 6 ) & 0x3F),
                                    0x80 | ( x         & 0x3F));
    else if(x <= 0x1FFFFF)
      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
                                    0x80 | ((x >>> 12) & 0x3F),
                                    0x80 | ((x >>> 6 ) & 0x3F),
                                    0x80 | ( x         & 0x3F));
  }
  return output;
}

/*
 * Encode a string as utf-16
 */
function str2rstr_utf16le(input)
{
  var output = "";
  for(var i = 0; i < input.length; i++)
    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
                                  (input.charCodeAt(i) >>> 8) & 0xFF);
  return output;
}

function str2rstr_utf16be(input)
{
  var output = "";
  for(var i = 0; i < input.length; i++)
    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
                                   input.charCodeAt(i)        & 0xFF);
  return output;
}

/*
 * Convert a raw string to an array of little-endian words
 * Characters >255 have their high-byte silently ignored.
 */
function rstr2binl(input)
{
  var output = Array(input.length >> 2);
  for(var i = 0; i < output.length; i++)
    output[i] = 0;
  for(var i = 0; i < input.length * 8; i += 8)
    output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32);
  return output;
}

/*
 * Convert an array of little-endian words to a string
 */
function binl2rstr(input)
{
  var output = "";
  for(var i = 0; i < input.length * 32; i += 8)
    output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
  return output;
}

/*
 * Calculate the MD5 of an array of little-endian words, and a bit length.
 */
function binl_md5(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;

  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;

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

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

    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

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

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  return Array(a, b, c, d);
}

/*
 * These functions implement the four basic operations the algorithm uses.
 */
function md5_cmn(q, a, b, x, s, t)
{
  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function md5_ff(a, b, c, d, x, s, t)
{
  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t)
{
  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t)
{
  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t)
{
  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_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 bit_rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}
