// ************** LICENCE ****************
// Copyright (c) 2007 Cyril Bosselut and contributors. All rights reserved.
// this script is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License
// 
// ***************************************
// Created by Cyril Bosselut on 04/07/2007
// ***************************************
var debugMode = false;
var updaters = new Array;
var messages = new Array;
var result = new Array;
/** globals functions **/

/**
 * test if browser is Internet Exploder
 *
 */
var IE = function(){
	if(document.all && !window.opera){
		return true;
	}
	return false;
}

/**
 * get element by ID
 *
 * @param eid (string) the element ID
 */
function _gid(eid){
	return document.getElementById(eid);
}

/**
 * get window width
 *
 */
function windowWidth(){
	if(IE()){
		return document.body.clientWidth;
	}
	else{
		return window.innerWidth;
	}
}

/**
 * get window height
 *
 */
function windowHeight(){
	if(IE()){
		return document.body.clientHeight;
	}
	else{
		return window.innerHeight;
	}
}

/**
 * get cursor position on X axis
 *
 * @param e (object) mouse event
 */
function getMouseX(e){
	if(IE()){
		return event.clientX + document.body.scrollLeft;
	}
	else{
		return e.clientX + window.pageXOffset;
	}
}

/**
 * get cursor position on Y axis
 *
 * @param e (object) mouse event
 */
function getMouseY(e){
	if(IE()){
		return event.clientY + document.body.scrollTop;
	}
	else{
		return e.clientY + window.pageYOffset;
	}
}

/**
 * get clicked button number
 *
 * @param e (object) mouse event
 */
function getMouseButton(e){
	if(IE()){
		switch(event.button){
			case 1:
				if(debugMode){
					jsterm.innerHTML = 'Mouse button 1';
				}
				return 1;
				break;
			case 2:
				if(debugMode){
					jsterm.innerHTML = 'Mouse button 3';
				}
				return 3;
				break;
			case 4:
				if(debugMode){
					jsterm.innerHTML = 'Mouse button 2';
				}
				return 2;
				break;
			default:
				if(debugMode){
					jsterm.innerHTML = 'Mouse button ' + event.button;
				}
				return event.button;
				break;
		}
	}
	else{
		if(debugMode){
			jsterm.innerHTML = 'Mouse button ' + e.which;
		}
		return e.which;
	}
}

/**
 * get event type
 *
 * @param e (object) event
 */
function getEventType(e){
	if(IE()){
		return event.type;
	}
	else{
		return e.type;
	}
}

/**
 * get event target
 *
 * @param e (object) event
 */
function getEventTarget(e){
	if(IE()){
		return event.srcElement;
	}
	else{
		return e.target;
	}
}

/**
 * get keyboard key number
 *
 * @param e (object) keyboard event
 */
function getKeynum(e){
	if(window.event){
		return e.keyCode;
	}
	else if(e.which){
		return e.which;
	}
}

/**
 * get keyboard key name
 *
 * @param e (object) keyboard event
 */
function getKeyname(code){
	return String.fromCharCode(code);
}

/**
 * page scroll to element position
 *
 * @param eid (string) the element ID
 */
function scrollToId(eid) {
	el = _gid(eid);
	var x = el.x ? el.x : el.offsetLeft
	var y = el.y ? el.y : el.offsetTop;
	window.scrollTo(x, y-20);
}

/**
 * page scroll to child element position
 *
 * @param pid (string) the parent element ID
 * @param cid (string) the child element ID
 */
function scrollToChild(pid,cid) {
	var p = _gid(pid);
	var c = _gid(cid);
	p.scrollLeft = c.x ? c.x : c.offsetLeft
	p.scrollTop = c.y ? c.y : c.offsetTop;
}

/**
 * hide block element
 *
 * @param el (object) the element
 */
function hide(el){
	el.style.display = 'none';
}

/**
 * show block element
 *
 * @param el (object) the element
 */
function show(el){
	el.style.display = 'block';
}

/**
 * show/hide block element
 *
 * @param el (object) the element
 */
function toggle(el){
	if(el.style.display == 'block'){
		hide(el);
	}
	else{
		show(el);
	}
}

/**
 * focus on element
 *
 * @param el (object) the element
 */
function focusElement(el) {
	el.focus();
	if(el.select){
		el.select();
	}
}

/**
 * set element opacity
 *
 * @param el (object) the element
 * @param val (double) opacity value from 0(transparent) to 1(opaque)
 */
function setOpacity(el,val){
	if(IE()){
		el.style.filter="alpha(opacity="+(val*100)+")";
	}
	else{
		el.style.opacity = val;
	}
}

/**
 * progressive opacification
 *
 * @param block (string) the element id
 * @param clear (bool) if true make transparent
 * @param callback (function) callback function
 */
function opacify(block, clear, callback){
	el = _gid(block);
	if(el != undefined){
		var currentOpacity = 0;
		if(IE()){
			var reg = /([0-9]+)/;
			if(reg.test(el.style.filter)){
				currentOpacity = parseInt(el.style.filter.match(reg))/100;
			}
		}
		else{
			if(el.style.opacity != ""){
				currentOpacity = parseFloat(el.style.opacity);
			}
			else{
				if(clear){
					currentOpacity = 1;
				}
				else{
					currentOpacity = 0;
				}
			}
		}
		if(clear){
			if(currentOpacity > 0){
				setOpacity(el,currentOpacity - 0.2);
				return setTimeout("opacify('"+block+"',true,"+callback+")",70);
			}
			else if(callback){
				callback(block);
			}
		}
		else{
			if(currentOpacity < 1){
				setOpacity(el,currentOpacity + 0.2);
				return setTimeout("opacify('"+block+"',false,"+callback+")",50);
			}
			else if(callback){
				callback(block);
			}
		}
	}
}

/**
 * change element inner HTML
 *
 * @param tg (string) target element
 * @param c (string) HTML content
 * @param callback (function) callback function
 */
function updateContent(tg,c,callback){
	_gid(tg).innerHTML = c;
	if(callback){
		callback(tg);
	}
}

/**
 * change form field value
 *
 * @param tg (string) target element
 * @param v (string) text value
 */
function setFieldValue(tg,v){
	_gid(tg).value = v;
}

/**
 * add text into a form field value
 * if field have text selected txt[0] is place before selection and txt[1] after
 * if repl == true, value is replace by txt
 *
 * @param tg (string) target element
 * @param txt (2 elements array) text to add
 * @param repl (bool) replace value
 */
function addtext(tg, txt, repl) {
	if(repl){
		setFieldValue(tg, txt);
	}
	else{
		var myField = _gid(tg);
		if (typeof(document["selection"]) != "undefined") {
			myField.focus();
			sel = document.selection.createRange();
			sel.text = txt[0] + sel.text + txt[1];
		}
		else if (myField.selectionStart || myField.selectionStart == '0') {
			var startPos = myField.selectionStart;
			var endPos = myField.selectionEnd;
			setFieldValue(tg, myField.value.substring(0, startPos) + txt[0] + myField.value.substring(startPos, endPos) + txt[1] + myField.value.substring(endPos, myField.value.length));
		}
		else{
			setFieldValue(tg, myField.value + txt[0] + txt[1]);
		}
	}
}

/**
 * Create an XMLHttpRequest object
 */
function initAjax(){
	if (window.XMLHttpRequest){
		return new XMLHttpRequest();     // Firefox, Safari, ...
	}
	else if (window.ActiveXObject){
		return new ActiveXObject('Microsoft.XMLHTTP');    // Internet Explorer 
	}
	else{
		return false;
	}
}

/**
 * Send a GET XMLHttpRequest
 *
 * @param p (string) the script url which will be called
 * @param xhr (object) XMLHttpRequest object
 */
function getAjax(p,xhr){
	xhr.open("GET",p,true);
	xhr.send(null);
}

/**
 * Send a POST XMLHttpRequest
 *
 * @param p (string) the script url which will be called
 * @param xhr (object) XMLHttpRequest object
 */
function postAjax(p,xhr, data){
	xhr.open("POST",p,true);
	xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	xhr.send(data);
}

/**
 * Perform an asynchronious request and send result to callback function
 *
 * @param url (string) the script url which will be called
 * @param callback (function) function executed on script response
 * @param args (object) parameters sent to callback function
 */
function remoteCall(url, callback, args, method, data){
	var re = /.+/;
	var xhr = initAjax();
	if(method == 'POST'){
		postAjax(url,xhr,'data='+data);
	}
	else{
		getAjax(url,xhr);
	}
	xhr.onreadystatechange = function(){
/*		if(xhr.readyState == 1){
				
		}*/
		if(xhr.readyState == 4){
			var mText = xhr.responseText;
			//if(mText.match(re)){
				callback(mText, args);
			//}
		}
	}
}

/**
 * Perform an asynchronious request and write result into HTML element
 *
 * @param pg (string) the script url which will be called
 * @param tg (string) the target element
 * @param spin (bool) display an animation in target element while loading
 * @param noscroll (bool) scroll page to target element (default true)
 */
function getHTML(pg,tg,spin,noscroll){
	var mBlock = _gid(tg);
	if(mBlock){
		if(spin == true){
			showSpinner(mBlock);
		}
		mBlock.style.cursor='wait';
		remoteCall(pg, function(r, args){
			_gid(args.target).innerHTML = r;
			if(!noscroll){
				scrollToId(args.target);
			}
			_gid(args.target).style.cursor='default';
		},{target:tg});
	}
}

/**
 * Perform an asynchronious request and evaluate result as javascript
 *
 * @param script (string) the script url which will be called
 */
function getJS(script){
	remoteCall(script, function(r){eval(r)});
}

/**
 * Perform an asynchronious request (GET) and evaluate result as json object
 *
 * @param script (string) the script url which will be called
 * @param obj (string) name of the object where we store result
 * @param callback (function) function executed on script response
 */
function getJSON(script, obj, callback){
	remoteCall(script, function(r,args){
		var cmd = args+'='+r;
		eval(cmd);
		try{
			callback(r);
		}
		catch(err){
			return false;
		}
	}, obj);
}

/**
 * Perform an asynchronious request (POST) and evaluate result as json object
 *
 * @param script (string) the script url which will be called
 * @param obj (string) name of the object where we store result
 * @param data (string) JSON string sended by POST as `data`
 * @param callback (function) function executed on script response
 */
function postJSON(script, obj, data, callback){
	remoteCall(script, function(r,args){
		eval(args+'='+r);
		try{
			callback(r);
		}
		catch(err){
			return false;
		}
		
	}, obj,'POST',data);
}


/**
 * replace element content by a loading animation
 *
 * @param el (object) the element
 */
function showSpinner(el){
	el.innerHTML = '<img src="'+base_uri+'images/spinner.gif" class="spinner" />';
}


/**
 * create an HTML tr->td structure in a target element (table or tbody) using an object as source
 *
 * @param obj (object) two dimension object
 * @param target (string) target element's HTML id
 */
function arrayToHTML(obj, target, callback){
	var tg = _gid(target);
	tg.innerHTML = '';
	var trclass = 'impair';
	var r = 1;
	for(row in obj){
		var tr = document.createElement('tr');
		tr.className = trclass + ' tr' + r++;
		tr.rel = row;
		if(trclass == 'impair'){
			trclass = 'pair';
		}
		else{
			trclass = 'impair';
		}
		var tdclass = 'impair';
		var c = 1;
		for(col in obj[row]){
			var td = document.createElement('td');
			td.innerHTML = obj[row][col];
			td.className = tdclass + ' td' + c++;
			if(tdclass == 'impair'){
				tdclass = 'pair';
			}
			else{
				tdclass = 'impair';
			}
			tr.appendChild(td);
		}
		tg.appendChild(tr);
	}
	if(callback){
		callback();
	}
}
/** end globals functions **/

function jsonReceived(callback){
	for(i in updaters){
		eval(updaters[i]);
	}
	if(callback){
		callback();
	}
}

function setClassName(className,target){
	_gid(target).className=className;
}

function initUpdaters(){
	updaters = new Array();
}

function addContentUpdater(source,target, callback){
	updaters.push('updateContent("'+target+'",'+source+', '+callback+')');
}

function addTableUpdater(source,target, callback){
	updaters.push('arrayToHTML('+source+',"'+target+'", '+callback+')');
}

function addClassUpdater(className,target){
	updaters.push('setClassName('+className+',"'+target+'")');
}

function editCellAsText(td,callback,args){
	args.old = td.innerHTML;
	args.input = document.createElement('input');
	args.input.type = 'text';
	args.input.className = 'textinput';
	args.input.value = args.old;
	td.innerHTML = '';
	args.input.onblur = function(e){
		callback(args);
	}
	args.input.onkeypress = function(e){
		if(getKeynum(e) == 13){
			callback(args);
		}
	}
	td.appendChild(args.input);
	focusElement(args.input);
}

function editCellAsList(td,values,callback,args){
	args.old = td.innerHTML;
	args.select = document.createElement('select');
	args.select.className = 'select';
	args.options = new Array;
	for(i in values){
		args.options[i] = document.createElement('option');
		args.options[i].value = i;
		args.options[i].text = values[i];
		if(values[i] == args.old){
			args.options[i].selected = 'true';
		}
		args.select.appendChild(args.options[i]);
	}
	td.innerHTML = '';
	args.select.onblur = function(e){
		callback(args);
	}
	args.select.onchange = function(e){
		callback(args);
	}
	args.select.onkeypress = function(e){
		if(getKeynum(e) == 13){
			callback(args);
		}
	}
	td.appendChild(args.select);
	focusElement(args.select);
}

function toggleCellValue(td, values, callback, args){
	args.old = td.innerHTML;
	if(args.old == values[0]){
		args.value = values[1];
		td.innerHTML = values[1];
	}
	else{
		args.value = values[0];
		td.innerHTML = values[0];
	}
	callback(args);
}

function stopTextSelection(){
	document.onmousedown=function(){return false};
	document.onselectstart=function(){return false};
}

function radioValue(el){
	for(i in el){
		if(el[i].checked != undefined && el[i].checked === true){
			return el[i].value;
		}
	}
	return false;
}
