
var FastInit = {
	onload : function() {
		if (FastInit.done) { return; }
		FastInit.done = true;
		for(var x = 0, al = FastInit.f.length; x < al; x++) {
			FastInit.f[x]();
		}
	},
	addOnLoad : function() {
		var a = arguments;
		for(var x = 0, al = a.length; x < al; x++) {
			if(typeof a[x] === 'function') {
				if (FastInit.done ) {
					a[x]();
				} else {
					FastInit.f.push(a[x]);
				}
			}
		}
	},
	listen : function() {
		if (/WebKit|khtml/i.test(navigator.userAgent)) {
			FastInit.timer = setInterval(function() {
				if (/loaded|complete/.test(document.readyState)) {
					clearInterval(FastInit.timer);
					delete FastInit.timer;
					FastInit.onload();
				}}, 10);
		} else if (document.addEventListener) {
			document.addEventListener('DOMContentLoaded', FastInit.onload, false);
		} else if(!FastInit.iew32) {
			if(window.addEventListener) {
				window.addEventListener('load', FastInit.onload, false);
			} else if (window.attachEvent) {
				return window.attachEvent('onload', FastInit.onload);
			}
		}
	},
	f:[],done:false,timer:null,iew32:false
};
FastInit.listen();
var mt = {
	config:{
		enableTabs:false,
		enableSuperCombos:false
	},
	dom:{
		getChildrenByTagName:function(node, tagName) {
			var ln = node.childNodes.length;

			var arr = [];
			for (var z=0; z<ln; z++) {
				if (node.childNodes[z].nodeType==1 && node.childNodes[z].nodeName.toUpperCase()==tagName.toUpperCase()) arr.push(node.childNodes[z]);
			}
			return arr;
		},
		disableSelection:function(n) {
			try{
				n.style.MozUserSelect = "none";
				n.unselectable = "on";
				n.style.KhtmlUserSelect = "none";
			}catch(e){};
		},
		getValueByTagName:function(node, nodeName, defaultValue) {
			var defaultValue = (defaultValue) ? defaultValue : "";
			var n = node.getElementsByTagName(nodeName)[0];
	   		return (n && n.firstChild) ? n.firstChild.nodeValue : defaultValue;
		}
	},
	utils:{
		displayFormFieldMsg:function(field, msg) {
			try{field.removeInfosMsgFunc();}catch(e){};
			var pos = Position.cumulativeOffset(field);
			var span = document.createElement("span");
			span.style.position = "absolute";
			span.style.backgroundColor = "#FFFFCC";
			span.style.padding = "1px 3px 1px 3px";
			span.style.border = "1px solid #CC9933";
			span.style.font = "10px Arial";
			span.innerHTML = msg;
			span.style.top = pos[1]+(Element.getHeight(field)/2)-9+"px";
			span.style.left = pos[0]+Element.getWidth(field)+5+"px";
			span.style.zIndex = 998;
			document.body.appendChild(span);
			function removeMsg(){
				Element.remove(span);
				field.style.borderColor = "#7F9DB9";
				Event.stopObserving(field, 'focus', removeMsg);
			}
			Event.observe(field, 'focus', removeMsg);
			field.removeInfosMsgFunc = removeMsg;
			field.style.borderColor = "red";
		},
		displayFormInputErrorMsg:function(form, elm, msg){
			while(elm.nodeName!="TR") {elm = elm.parentNode};
			var td = elm.getElementsByTagName("td")[0];
			td.style.backgroundColor = "#FFEFEF";
			var div = document.createElement("div");
			div.className = "errorMsg";
			div.innerHTML = msg;
			td.appendChild(div);
			if (!form.isErrorAnchorSet) {
				td.id = "firstErrorAnchor";
				form.isErrorAnchorSet = true;
			}
		},
		cleanFormInputErrorMsgs:function(form){
			form.isErrorAnchorSet = false;
			$A($C("errorMsg", form)).each(function(item){
				var elm = item;
				while(elm.nodeName!="TD") {elm = elm.parentNode};
				elm.id = null;
				elm.style.backgroundColor = "#EFF5FF";
				item.remove();
			});
		},
		getQuestionMarks:function(num) {
			var str = [];
			(num).times(function(){str.push("?");});
			return str.join(",");
		},
		showModal:function(str) {
			alert(str);
		},
		displayPopup:function(url, width, height, options) {
			window.open(url,'','scrollbars=yes,resizable=yes,width='+width+',height='+height);
		}
	},
	html:{
		CheckboxCollection:function(domId, lineBreak){
			var self = this;
			this.div = $(domId);
			this.div.style.lineHeight = "1.5em";
			var rnd = parseInt(Math.random()*1000);
			this.setDataSet = function(dataSet, valueName, labelName) {
				dataSet.each(function(item){
					var input = document.createElement("input");
					var label = document.createElement("label");
					input.type = "checkbox";
					input.id = "checkbox_"+rnd+"_"+item[valueName];
					input.value = item[valueName];
					label.innerHTML = item[labelName];
					label.setAttribute("for", "checkbox_"+rnd+"_"+item[valueName]);
					mt.dom.disableSelection(label);
					self.div.appendChild(input);
					self.div.appendChild(label);
					if (lineBreak) self.div.appendChild(document.createElement("br"));
				});
			}
			this.setSelectedValues = function(values, labelName) {
				var checkboxes = $A(self.div.getElementsByTagName("input"));
				values.each(function(item){
					checkboxes.each(function(chk){
						if (labelName) {
							if (chk.value==item[labelName]) chk.checked = true;
						} else {
							if (chk.value==item) chk.checked = true;
						}
					});
				});
			}
			this.getSelectedValues = function() {
				var arr = [];
				var checkboxes = $A(self.div.getElementsByTagName("input"));
				checkboxes.each(function(chk){
					if (chk.checked) arr.push(chk.value);
				});
				return arr;
			}
		},
		enableSuperCombos:function() {
			var combos = document.getElementsByTagName("select");
			for (var z=0; z<combos.length; z++) {
				mt.html.setSuperCombo(combos[z]);
			}
		},
		setSuperCombo:function(combo) {
			combo.addItem = function(itemObj) {
				this.options[this.options.length] = new Option(itemObj.value, itemObj.data);
			}
			combo.populate = function(dataSet, selectionValue, valueName, labelName) {
				this.removeAll();
				dataSet.each(function(item, index){
					var value = (valueName) ? dataSet[index][valueName] : dataSet[index].data;
					var label = (labelName) ? dataSet[index][labelName] : dataSet[index].value;
					var opt = new Option(label, value);
					combo.options[index] = opt;
					if (opt.value==selectionValue) combo.selectedIndex = index;
				});
			}
			combo.setSelectedValue = function(value) {
				for (var z=0; z<this.options.length; z++) {
					if (this.options[z].value==value) {
						this.selectedIndex = z;
						break;
					}
				}
			}
			combo.setSelectedValues = function(values, labelName) {
				values.each(function(item){
					for (var z=0; z<combo.options.length; z++) {
						if (labelName) {
							if (combo.options[z].value==item[labelName]) combo.options[z].selected = true;
						} else {
							if (combo.options[z].value==item) combo.options[z].selected = true;
						}
					}
				});
			}
			combo.getSelectedValues = function() {
				var arr = [];
				for (var z=0; z<this.options.length; z++) {
					if (this.options[z].selected) arr.push(this.options[z].value);
				}
				return arr;
			}
			combo.setSelectedIndex = function(index) {
				this.selectedIndex = index;
			}
			combo.getSelectedText = function() {
				return this.options[this.selectedIndex].text;
			}
			combo.removeItem = function(index) {
				this.options[index] = null;
			}
			combo.removeAll = function() {
				this.options.length = 0;
			}
		}
	},
	component:{
		getComponent:function(cptName) {
			
		}
	}
};

/* ======== STRING PROTOTYPES ======== */

String.prototype.trim = function() {
	return this.replace(/^\s*|\s*$/g,"");
}

String.prototype.replaceSpecialChars = function(newStr) {
     re = /\$|,|@|#|~|`|\%|\*|\^|\&|\(|\)|\+|\=|\[|\-|\_|\]|\[|\}|\{|\;|\:|\'|\"|\<|\>|\?|\||\\|\!|\$|\./g;
     return this.replace(re, newStr);
}

String.prototype.isNull = function() {
	return (this.trim()=='');
}

String.prototype.isEmail = function() {
	var str = this.trim();
	var ok = "1234567890qwertyuiop[]asdfghjklzxcvbnm.+@-_QWERTYUIOPASDFGHJKLZXCVBNM";
	for(var i=0; i<str.length; i++){
		if (ok.indexOf(str.charAt(i))<0) {
			return false;
		}
	}
	if (document.images) {
		var re = /(@.*@)|(\.\.)|(^\.)|(^@)|(@$)|(\.$)|(@\.)/;
		var re_two = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,8}|[0-9]{1,3})(\]?)$/;
		if (!str.match(re) && str.match(re_two)) {
			return -1;
		}
	}
}

String.prototype.isNumber = function() {
	var str = this.trim();	
	var regEx=/^[0-9]+$/;
	return regEx.test(str);
}

String.prototype.isFloat = function() {
	var str = this.trim();
	var regEx=/^[0-9.]+$/;
	return regEx.test(str);
}

String.prototype.isAlpha = function() {
	var str = this.trim();
	var regEx=/^[A-Za-z]+$/;
	return regEx.test(str);
}

String.prototype.isAlphaNumeric = function() {
	var str = this.trim();
	return /^[a-zA-Z0-9_\d]+$/.test(str);
};

String.prototype.isDate = function(){
	var str = this.trim();
	var datePattern = /^\d{1,2}[\/-]\d{1,2}[\/-]\d{4}$/;
	return datePattern.test(str);
}

String.prototype.addSlashes = function(){
	return this.replace(/\\/g,"\\\\").replace(/\'/g,"\\'").replace(/\"/g,"\\\"");
}

/* ========NUMBER PROTOTYPES ======== */

Object.extend(Number.prototype, {
	to2Digits: function() {
		var digits = this.toString();
		return (digits.length==1) ? ('0'+digits) : digits;
	}
});

var $C = document.getElementsByClassName;


Array.prototype.randomize = function(){
	var i = this.length;
	if (i==0) return false;
	while(--i){
		var j = Math.floor(Math.random()*(i+1));
		var tempi = this[i];
		var tempj = this[j];
		this[i] = tempj;
		this[j] = tempi;
   }
}



function activateFormFieldsValidation() {

	var isValid;

	function checkElement(item) {
		if (Element.hasClassName(item, 'dataType-notNull')) {
			if (item.value.isNull()) {
				mt.utils.displayFormFieldMsg(item, "Ne doit pas être vide");
				isValid = false;
			}
		}
		
		if (Element.hasClassName(item, 'dataType-email')) {
			if (!item.value.isEmail() && !item.value.isNull()) {
				mt.utils.displayFormFieldMsg(item, "L'adresse email n'est pas valide");
				isValid = false;
			}
		}
		
		if (Element.hasClassName(item, 'dataType-integer')) {
			if (!item.value.isNumber() && !item.value.isNull()) {
				mt.utils.displayFormFieldMsg(item, "Ne doit contenir que des chiffres");
				isValid = false;
			}
		}
		
		if (Element.hasClassName(item, 'dataType-float')) {
			if (!item.value.isFloat() && !item.value.isNull()) {
				mt.utils.displayFormFieldMsg(item, "Ne doit contenir que des chiffres");
				isValid = false;
			}
		}
		
		if (Element.hasClassName(item, 'dataType-alpha')) {
			if (!item.value.isAlpha() && !item.value.isNull()) {
				mt.utils.displayFormFieldMsg(item, "Ne doit contenir que des lettres");
				isValid = false;
			}
		}
		
		if (Element.hasClassName(item, 'dataType-alphaNumeric')) {
			if (!item.value.isAlphaNumeric() && !item.value.isNull()) {
				mt.utils.displayFormFieldMsg(item, "Ne doit contenir que des caractères alphanumériques");
				isValid = false;
			}
		}
		
		if (Element.hasClassName(item, 'dataType-date')) {
			if (!item.value.isDate() && !item.value.isNull()) {
				mt.utils.displayFormFieldMsg(item, "La date n'est pas valide");
				isValid = false;
			}
		}
		
		if (item.className.indexOf('dataType-minLength')!=-1) {
			item.classNames().each(function(c){
				if (c.indexOf('dataType-minLength')!=-1) {
					var length = c.split("-")[2];
					if (item.value.length<length) {
						mt.utils.displayFormFieldMsg(item, "Ce champ doit contenir au moins "+length+" caractères");
						isValid = false;
					}
					throw $break;
				}
			});
		}
		
		if (item.className.indexOf('dataType-maxLength')!=-1) {
			item.classNames().each(function(c){
				if (c.indexOf('dataType-maxLength')!=-1) {
					var length = c.split("-")[2];
					if (item.value.length>length) {
						/*
						<textarea onkeyup="this.value = this.value.slice(0, 500)" onchange="this.value = this.value.slice(0, 500)">
						(remplacer 500 par le nombre max. de caractères)
						*/
						mt.utils.displayFormFieldMsg(item, "Ce champ ne doit pas contenir plus de "+length+" caractères.");
						isValid = false;
					}
					throw $break;
				}
			});
		}

	}
	
	function applyBlurEvent(item) {
		Event.observe(item, 'blur', function(){
			checkElement(item);
		});
	}

	$$('form.validate-fields').each(function(form){
		
		//$A(form.getElementsByTagName("input")).each(applyBlurEvent);
		//$A(form.getElementsByTagName("textarea")).each(applyBlurEvent);
		
		form.removeControlMessages = function() {
			$A(this.getElementsByTagName("input")).each(function(item){
				try{item.removeInfosMsgFunc();}catch(e){};
			});
			$A(this.getElementsByTagName("textarea")).each(function(item){
				try{item.removeInfosMsgFunc();}catch(e){};
			});
		}
		
		form.onsubmit = function() {
			try {
				isValid = this.isValid();
			} catch(e){
				isValid = true;
			}
			
			$A(this.getElementsByTagName("input")).each(checkElement);
			$A(this.getElementsByTagName("textarea")).each(checkElement);			
			
			if (this.ajaxSubmit && isValid) {
				try{this.onBeforeSubmit();}catch(e){}
				this.ajaxSubmit();
				return false;
			} else {
				try{
					if (isValid) {
						this.onBeforeSubmit();
					} else {
						this.onFailure();
					}
				}catch(e){}
				return isValid;
			}
		}
		
	});	
}

function activateDateFields() {
	$$('input.dataType-date').each(function(item){
		var span = document.createElement("span");
		var input = item.cloneNode(true);
		var self = this;
		var currentDate = input.value;
		
		span.appendChild(input);
		item.parentNode.insertBefore(span, item);
		Element.remove(item);
		
		span.style.position = "relative";
	
		var calframe = document.createElement("div");
		calframe.style.position = "absolute";
		calframe.style.left = 0;
		Element.hide(calframe);
	
		var calendar = new mt.component.Calendar(calframe);
		
		function applyValueDate() {
			if (!input.value.isNull() && input.value.isDate()) {
				var d = input.value.trim().split("/");
				calendar.setSelectedDate(new Date(parseFloat(d[2]), parseFloat(d[1])-1, parseFloat(d[0])));
			}
		}
		
		applyValueDate();
		
		calendar.onSelect = function(date) {
			input.value = date.getDate().to2Digits()+"/"+(date.getMonth()+1).to2Digits()+"/"+date.getFullYear();
			currentDate = input.value;
			hideCalendar();
		}
		calendar.render();
		
		function hideCalendar() {
			span.style.zIndex = 0;
			Element.hide(calframe);
			Event.stopObserving(document.body, 'click', hideCalendar);
		}
		
		function showCalendar(e) {
			try {window.openedPopupCalendarHideFunc();} catch(e){}
			window.openedPopupCalendarHideFunc = hideCalendar;
			span.style.zIndex = 998;
			Element.show(calframe);
			Event.stop(e);
			setTimeout(function() {
				Event.observe(document.body, 'click', hideCalendar);
			}, 1);
		}
		
		Event.observe(input, 'click', showCalendar);
		
		Event.observe(input, 'blur', function() {
			if (input.value.isDate()) {
				if (currentDate!=input.value) {
					currentDate = input.value;
					applyValueDate();
					calendar.updateCalendar(new Date(calendar.getSelectedDate()));
				}
			} else {
				if (currentDate!=input.value) {
					currentDate = input.value;
					calendar.setSelectedDate(null);
					calendar.updateCalendar(new Date());
				}
			}
		});
		
		calframe.style.top = Element.getHeight(input);
		span.appendChild(calframe);

	});
}

function activateRoundedCorners() {
	var defaultBorder = RUZEE.ShadedBorder.create({corner:4, border:2});
	$$('.roundCorners').each(function(item){
		item.addClassName("sb");
		defaultBorder.render(item);
	});
	
	$$('.round').each(function(item){
		var params = {};
		if (item.getAttribute("corner")) params.corner = parseInt(item.getAttribute("corner"));
		if (item.getAttribute("border")) params.border = parseInt(item.getAttribute("border"));
		if (item.getAttribute("edges")) params.edges = item.getAttribute("edges");
		item.addClassName("sb");
		RUZEE.ShadedBorder.create(params).render(item);
	});
}

function activateBtnMoovi() {

	var myBorder = RUZEE.ShadedBorder.create({corner:3, border:1});
	
	$$('.btnMoovi').each(function(item){
	
		var table = document.createElement("table");
		table.id = item.id;
		table.className = "btn_moovi";
		
		var tbody = document.createElement("tbody");
		var tr = document.createElement("tr");
		var td = document.createElement("td");
		
		var div = document.createElement("div");
		div.className = "btnFrame";
		var content = item.innerHTML;
		
		var div0 = document.createElement("div");
		div0.className = "sb btn btn_out";
		div0.style.padding = "2px";
		div0.style.cursor = "pointer";
		
		div0.appendChild(div);
		td.appendChild(div0);
		tr.appendChild(td);
		tbody.appendChild(tr);
		table.appendChild(tbody);
		
		item.parentNode.insertBefore(table, item);
		item.remove();
		div.innerHTML = content;
		
		myBorder.render(div0);
		div0.onmouseover = function() {
			this.className = "sb btn btn_over";
		}
		div0.onmouseout = function() {
			this.className = "sb btn btn_out";
		}
		
	});
}

function activateImagesReflections() {
	$$('.reflect').each(function(item){
		var rheight = null;
		var ropacity = null;
		
		var classes = item.className.split(' ');
		for (j=0;j<classes.length;j++) {
			if (classes[j].indexOf("rheight") == 0) {
				var rheight = classes[j].substring(7)/100;
			} else if (classes[j].indexOf("ropacity") == 0) {
				var ropacity = classes[j].substring(8)/100;
			}
		}
		
		ImageReflection.add(item, { height: rheight, opacity : ropacity});	
	});
}

function activateDisableOnClick() {
	$$('.disableOnClick').each(function(btn){
		Event.observe(btn, 'click', function(){
			btn.disabled = true;
		});
	});
}


/* ======== DEFAULT START ACTIONS ======== */


Event.observe(window, 'load', function(){

	activateRoundedCorners();
	mt.html.enableSuperCombos();
	activateDateFields();
	activateFormFieldsValidation();
	activateBtnMoovi();
	activateImagesReflections();
	activateDisableOnClick();
	
	try {onPageLoad();} catch(e){}
});

Event.observe(window, 'resize', function(){
	activateRoundedCorners();
});

/* ======== DATE HANDLING ======== */

/* check http://www.xaprb.com/articles/date-formatting-demo.html */
Date.formatFunctions = {count:0};

Date.prototype.dateFormat = function(format) {
    if (Date.formatFunctions[format] == null) {
        Date.createNewFormat(format);
    }
    var func = Date.formatFunctions[format];
    return eval("this." + func + "();");
}

Date.createNewFormat = function(format) {
    var funcName = "format" + Date.formatFunctions.count++;
    Date.formatFunctions[format] = funcName;
    var code = "Date.prototype." + funcName + " = function(){return ";
    var special = false;
    var chari = '';
    for (var i = 0; i < format.length; ++i) {
        chari = format.charAt(i);
        if (!special && chari == "\\") {
            special = true;
        }
        else if (special) {
            special = false;
            code += "'" + String.escape(chari) + "' + ";
        }
        else {
            code += Date.getFormatCode(chari);
        }
    }
    eval(code.substring(0, code.length - 3) + ";}");
}

Date.getFormatCode = function(character) {
    switch (character) {
    case "d":
        return "String.leftPad(this.getDate(), 2, '0') + ";
    case "D":
        return "Date.dayNames[this.getDay()].substring(0, 3) + ";
    case "j":
        return "this.getDate() + ";
    case "l":
        return "Date.dayNames[this.getDay()] + ";
    case "S":
        return "this.getSuffix() + ";
    case "w":
        return "this.getDay() + ";
    case "z":
        return "this.getDayOfYear() + ";
    case "W":
        return "this.getWeekOfYear() + ";
    case "F":
        return "Date.monthNames[this.getMonth()] + ";
    case "m":
        return "String.leftPad(this.getMonth() + 1, 2, '0') + ";
    case "M":
        return "Date.monthNames[this.getMonth()].substring(0, 3) + ";
    case "n":
        return "(this.getMonth() + 1) + ";
    case "t":
        return "this.getDaysInMonth() + ";
    case "L":
        return "(this.isLeapYear() ? 1 : 0) + ";
    case "Y":
        return "this.getFullYear() + ";
    case "y":
        return "('' + this.getFullYear()).substring(2, 4) + ";
    case "a":
        return "(this.getHours() < 12 ? 'am' : 'pm') + ";
    case "A":
        return "(this.getHours() < 12 ? 'AM' : 'PM') + ";
    case "g":
        return "((this.getHours() %12) ? this.getHours() % 12 : 12) + ";
    case "G":
        return "this.getHours() + ";
    case "h":
        return "String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + ";
    case "H":
        return "String.leftPad(this.getHours(), 2, '0') + ";
    case "i":
        return "String.leftPad(this.getMinutes(), 2, '0') + ";
    case "s":
        return "String.leftPad(this.getSeconds(), 2, '0') + ";
    case "O":
        return "this.getGMTOffset() + ";
    case "T":
        return "this.getTimezone() + ";
    case "Z":
        return "(this.getTimezoneOffset() * -60) + ";
    default:
        return "'" + String.escape(character) + "' + ";
    }
}

Date.prototype.getTimezone = function() {
    return this.toString().replace(
        /^.*? ([A-Z]{3}) [0-9]{4}.*$/, "$1").replace(
        /^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3");
}

Date.prototype.getGMTOffset = function() {
    return (this.getTimezoneOffset() > 0 ? "-" : "+")
        + String.leftPad(Math.floor(this.getTimezoneOffset() / 60), 2, "0")
        + String.leftPad(this.getTimezoneOffset() % 60, 2, "0");
}

Date.prototype.getDayOfYear = function() {
    var num = 0;
    Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
    for (var i = 0; i < this.getMonth(); ++i) {
        num += Date.daysInMonth[i];
    }
    return num + this.getDate() - 1;
}

Date.prototype.getWeekOfYear = function() {
    // Skip to Thursday of this week
    var now = this.getDayOfYear() + (4 - this.getDay());
    // Find the first Thursday of the year
    var jan1 = new Date(this.getFullYear(), 0, 1);
    var then = (7 - jan1.getDay() + 4);
    return String.leftPad(((now - then) / 7) + 1, 2, "0");
}

Date.prototype.isLeapYear = function() {
    var year = this.getFullYear();
    return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
}

Date.prototype.getFirstDayOfMonth = function() {
    var day = (this.getDay() - (this.getDate() - 1)) % 7;
    return (day < 0) ? (day + 7) : day;
}

Date.prototype.getLastDayOfMonth = function() {
    var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7;
    return (day < 0) ? (day + 7) : day;
}

Date.prototype.getDaysInMonth = function() {
    Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
    return Date.daysInMonth[this.getMonth()];
}

Date.prototype.getFirstDateOfWeek = function() {
	var numDay = (this.getDay()==0) ? 7 : this.getDay();
	this.setDate(this.getDate()-numDay+1);
	return this;
};
Date.prototype.getWeekNumber = function() {
	var when = this;
	var newYear = new Date(when.getFullYear(),0,1);
	var offset = 7 + 1 - newYear.getDay();
	if (offset == 8) offset = 1;
	var daynum = ((Date.UTC(y2k(when.getFullYear()),when.getMonth(),when.getDate(),0,0,0) - Date.UTC(y2k(when.getFullYear()),0,1,0,0,0)) /1000/60/60/24) + 1;
	var weeknum = Math.floor((daynum-offset+7)/7);
	if (weeknum == 0) {
		year--;
		var prevNewYear = new Date(year,0,1);
		var prevOffset = 7 + 1 - prevNewYear.getDay();
		if (prevOffset == 2 || prevOffset == 8) weeknum = 53; else weeknum = 52;
	}
	return weeknum;
}

function y2k(number) { return (number < 1000) ? number + 1900 : number; }


Date.prototype.getSuffix = function() {
    switch (this.getDate()) {
        case 1:
        case 21:
        case 31:
            return "st";
        case 2:
        case 22:
            return "nd";
        case 3:
        case 23:
            return "rd";
        default:
            return "th";
    }
}

String.escape = function(string) {
    return string.replace(/('|\\)/g, "\\$1");
}

String.leftPad = function (val, size, chari) {
    var result = new String(val);
    if (chari == null) {
        chari = " ";
    }
    while (result.length < size) {
        result = chari + result;
    }
    return result;
}

Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
Date.monthNames =
   ["Janvier",
    "Février",
    "Mars",
    "Avril",
    "Mai",
    "Juin",
    "Juillet",
    "Août",
    "Septembre",
    "Octobre",
    "Novembre",
    "Décembre"];
Date.dayNames =
   ["Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday"];
Date.patterns = {
    ISO8601LongPattern:"Y-m-d H:i:s",
    ISO8601ShortPattern:"Y-m-d",
    ShortDatePattern: "n/j/Y",
    LongDatePattern: "l, F d, Y",
    FullDateTimePattern: "l, F d, Y g:i:s A",
    MonthDayPattern: "F d",
    ShortTimePattern: "g:i A",
    LongTimePattern: "g:i:s A",
    SortableDateTimePattern: "Y-m-d\\TH:i:s",
    UniversalSortableDateTimePattern: "Y-m-d H:i:sO",
    YearMonthPattern: "F, Y"};

Date.parseIsoDate = function(dateString) {
    var result = new Date();
    var re = /^(\d\d\d\d)-(\d\d)-(\d\d)( (\d\d):(\d\d):(\d\d)).(\d)*$/;
    var re2 = /^(\d\d\d\d)-(\d\d)-(\d\d)( (\d\d):(\d\d):(\d\d))?$/;
    var match = dateString.match(re) || dateString.match(re2);
    if (match != null) {
        if (match[5] != null && match[5] != '') {
            result = new Date(
                parseInt(match[1], 10),
                parseInt(match[2], 10) - 1,
                parseInt(match[3], 10),
                parseInt(match[5], 10),
                parseInt(match[6], 10),
                parseInt(match[7], 10));
        }
        else {
            result = new Date(
                parseInt(match[1], 10),
                parseInt(match[2], 10) - 1,
                parseInt(match[3], 10));
        }
    }
    return result;
}


function isNotNull(item) {
	if (item==null || item=="" || item=="undefined" || item=="null") return false;
	return true;
}


function Table() {
	this.domNode = document.createElement("TABLE");
	this.domNode.className = "formLayout";
	this.grid = document.createElement("TBODY");
	this.domNode.appendChild(this.grid);
	this.addLine = function(line) {
		this.grid.appendChild(line);
	}
}

function Line() {
	this.domNode = document.createElement("tr");
	this.addCell = function(cell) {
		this.domNode.appendChild(cell);
	}
}

function displayURL(sUrl) {location.href = sUrl;}


mt.component.ToolTip = function(node, content, width, align) {
	this.node = node;
	var self = this;
	this.content = content;
	this.width = (width==null)?150:width;
	this.align = (align==null)?"left":align;
	var offsetxpoint=0;
	var offsetypoint=20;
	this.domNode = document.createElement("div");	
	this.domNode.id = "tooltip";
	with(this.domNode.style){left="-1000px";position="absolute";zIndex="65432"};
	document.body.appendChild(this.domNode);

	this.init = function(){
		Event.observe(this.node, 'mousemove', this.setPosition.bindAsEventListener(this));
		Event.observe(this.node, 'click', this.remove.bindAsEventListener(this));
		Event.observe(this.node, 'mouseout', this.remove.bindAsEventListener(this));
		this.domNode.style.textAlign=this.align;
		this.domNode.innerHTML='<div class="tooltipFrame"><div class="tooltipFrame2">'+this.content+'</div></div>';
		this.domNode.style.width=(this.domNode.offsetWidth>this.width)?this.width:this.domNode.offsetWidth+"px";
		if (width) this.domNode.style.width=width+"px";
	}
	this.setPosition = function(e){
		var curX=(window.ActiveXObject)?e.clientX+document.body.scrollLeft:e.pageX;
		var curY=(window.ActiveXObject)?e.clientY+document.body.scrollTop:e.pageY;
		
		var rightedge=window.ActiveXObject? document.body.clientWidth-e.clientX-offsetxpoint : window.innerWidth-e.clientX-offsetxpoint-20;
		var bottomedge=window.ActiveXObject? document.body.clientHeight-e.clientY-offsetypoint : window.innerHeight-e.clientY-offsetypoint-20;
		
		var leftedge=(offsetxpoint<0)? offsetxpoint*(-1) : -1000;
		
		if (rightedge<this.domNode.offsetWidth) {
			this.domNode.style.left=(window.ActiveXObject) ? document.body.scrollLeft+e.clientX-this.domNode.offsetWidth+"px" : window.pageXOffset+e.clientX-this.domNode.offsetWidth+"px";
		} else if (curX<leftedge) {
			this.domNode.style.left="5px";
		} else {
			this.domNode.style.left=curX+offsetxpoint+"px";
		}
		
		if (bottomedge<this.domNode.offsetHeight) {
			var d = (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0 : window.pageYOffset;
			this.domNode.style.top=(window.ActiveXObject)? document.body.scrollTop+e.clientY-this.domNode.offsetHeight-offsetypoint+"px" : d+e.clientY-this.domNode.offsetHeight-offsetypoint+"px";
		} else {
			this.domNode.style.top=curY+offsetypoint+"px";
		}
	}
	this.remove = function(){
		Event.stopObserving(this.node, 'mouseout', this.remove.bindAsEventListener(this));
		Event.stopObserving(this.node, 'click', this.remove.bindAsEventListener(this));
		Event.stopObserving(this.node, 'mousemove', this.setPosition.bindAsEventListener(this));
		Element.remove(this.domNode);
	}
	this.init();
}

function Modal(title, mainContent) {
	var self = this;
	
	this.display = function() {
		try{Element.remove($('modal'))} catch(e){}
		
		this.divModal = document.createElement("form");
		this.divModal.action = "";
		this.divModal.style.zIndex = 10;
		this.divModal.id = "modal";
		var frame = document.createElement("div");
		frame.className = "modalFrame";
		var frame2 = document.createElement("div");
		frame2.className = "modalFrame2";
		var header = document.createElement("div");
		header.className = "header";
		header.innerHTML = title;
		this.content = document.createElement("div");
		this.content.className = "content";
		this.content.innerHTML = mainContent;

		var divButtons = document.createElement("div");
		divButtons.className = "buttons";

		var btnCancel = document.createElement("button");
		btnCancel.setAttribute("type", "button"); // for IE
		btnCancel.innerHTML = "Annuler";
		btnCancel.onclick = function() {
			self.remove();
		}

		var btnValidate = document.createElement("button");
		btnValidate.setAttribute("type", "submit"); // for IE
		btnValidate.innerHTML = "Valider";
		
		function submit() {
			self.onValidate();
			self.remove();
			return false;
		}
		
		this.divModal.onsubmit = btnValidate.onclick = submit;

		divButtons.appendChild(btnValidate);
		divButtons.appendChild(btnCancel);
	
		frame2.appendChild(header);
		frame2.appendChild(this.content);
		frame2.appendChild(divButtons);
		frame.appendChild(frame2);
		this.divModal.appendChild(frame);
		document.body.appendChild(this.divModal);
		this.updatePosition();
	}
	
	this.updatePosition = function() {
		this.divModal.style.top = document.documentElement.scrollTop+150+"px";
		this.divModal.style.left = ((document.documentElement.offsetWidth/2)-(this.divModal.offsetWidth/2))+"px";
	}
	
	this.onValidate = function(){};
	
	this.remove = function() {
		Element.remove(this.divModal);
	}
	
	this.display();
}

mt.component.DataGrid = Class.create();
mt.component.DataGrid.prototype = {
	initialize:function(placeHolder) {
		this.domNode = $(placeHolder);
		this.dataSet = [];
		this.columnStyles = [];
		this.createTable();
	},
	createTable:function() {
		this.table = document.createElement("TABLE");
		//this.table.style.width = "100%";
		this.table.className = "dataGrid";
		this.table.jsObj = this;
		this.grid = document.createElement("TBODY");
		this.table.appendChild(this.grid);
	},	
	addStyle:function(name, value) {
		this.table.style[name] = value;
	},
	setHeader:function(values) {
		var self = this;
		var line = document.createElement("tr");
		line.className = "header";
		values.each(function(item, index){
			var cell = document.createElement("td");
			cell.className = "cell";
			for (i in self.columnStyles[index]) {
				if (i=="width" || i=="textAlign")
				cell.style[i] = self.columnStyles[index][i];
			}
			if(typeof(item)=='object') {
				cell.appendChild(item);
			} else {
				cell.innerHTML = item;
			}
			line.appendChild(cell);
		});
		if (this.moveOptionEnabled) {
			var cell = document.createElement("td");
			cell.className = "cell";
			line.appendChild(cell);
		}
		if (this.removeOptionEnabled) {
			var cell = document.createElement("td");
			cell.className = "cell";
			cell.style.width = "16px";
			if (this.removeOptionHeader)
				cell.appendChild(this.removeOptionHeader);
			line.appendChild(cell);
		}
		this.grid.insertBefore(line, this.grid.firstChild);
	},
	/*setGridHeight:function(h) {
		this.grid.style.overflow = "auto";
		this.grid.style.height = h+"px";
	},*/
	_addItem:function(index, values, options) {
		var self = this;
		var line = document.createElement("tr");
		line.className = "line";
		for (i in this.linesStyle) line.style[i] = this.linesStyle[i];
		line.index = index;
		var lineData = {node:line, cells:[]};
		if (options)
			lineData.removeOption = options.removeOption;
		values.each(function(item, index){
			if (item==null) item="";
		
			var cell = document.createElement("td");
			cell.className = "cell";
			for (i in self.columnStyles[index]) cell.style[i] = self.columnStyles[index][i];
			cell.getIndex = function() {
				return this.parentNode.index;
			}
			var content;
			
			if (item.editable) {
				cell.innerHTML = item.value;
				cell.data = item.data;
				cell.editor = new mt.component.InPlaceEditor(cell, false);
				cell.editor.onChange = function(value) {
					cell.data = value;
				}
			} else {
			
				if (item.nodeType==1) {
					cell.data = "";
					content = item;
					cell.appendChild(content);
				} else {
					if (!item.value) {
						cell.data = "";
						content = item;
					} else {
						cell.data = item.data;
						content = item.value;
					}
					if (content.nodeType==1) {
						cell.appendChild(content);
					} else {
						cell.innerHTML = content;
					}
				}
			
			}
			
			line.appendChild(cell);
			lineData.cells.push(cell);
		});
		
		if (this.moveOptionEnabled) {
			var imgUp = document.createElement("img");
			imgUp.src = rootPath+"images/icons/up.gif";
			imgUp.className = "pointer";
			imgUp.onclick = function() {
				self.moveItem(-1, this.parentNode.parentNode.index);
			}
			var imgDown = document.createElement("img");
			imgDown.src = rootPath+"images/icons/down.gif";
			imgDown.style.marginLeft = "2px";
			imgDown.className = "pointer";
			imgDown.style.marginLeft = "4px";
			imgDown.onclick = function() {
				self.moveItem(1, this.parentNode.parentNode.index);
			}
			var cell = document.createElement("td");
			cell.className = "cell";
			cell.getIndex = function() {
				return this.parentNode.index;
			}
			cell.appendChild(imgUp);
			cell.appendChild(imgDown);
			line.appendChild(cell);
			lineData.cells.push(cell);
		}
		
		if ((this.removeOptionEnabled && lineData.removeOption) || (this.removeOptionEnabled && lineData.removeOption==null)) {
			var imgDelete = document.createElement("img");
			imgDelete.src = rootPath+"images/delete.gif";
			imgDelete.className = "pointer";
			imgDelete.onclick = function() {
				var result = self.onBeforeRemove(this.parentNode.parentNode.index);
				if (result || result==null) {
					self.removeItem(this.parentNode.parentNode.index);
				}
			}
			var cell = document.createElement("td");
			cell.style.width = "16px";
			cell.className = "cell";
			cell.getIndex = function() {
				return this.parentNode.index;
			}
			cell.appendChild(imgDelete);
			line.appendChild(cell);
			lineData.cells.push(cell);
		}		
		
		if (index==this.dataSet.length) {
			this.grid.appendChild(line);
			this.dataSet.push(lineData);
		} else {
			this.grid.insertBefore(line, this.grid.childNodes[index]);
			this.dataSet.splice(index, 0, lineData);
		}
		
		return lineData;
	},
	addItem:function(values, options) {
		return this._addItem(this.dataSet.length, values, options);
	},
	insertItem:function(index, values, options) {
		var lineData = this._addItem(index, values, options);
		this._updateIndexes();
		return lineData;
	},
	_updateIndexes:function() {
		this.dataSet.each(function(line, index){
			line.node.index = index;
		});
	},
	setColumnStyle:function(index, styles) {
		this.columnStyles[index] = styles;
		this.dataSet.each(function(line){
			for (i in styles) {
				line.cells[index].style[i] = styles[i];
			}
		});
	},
	addRemoveOption:function(headerContent) {
		this.removeOptionHeader = headerContent;
		this.removeOptionEnabled = true;
		this.dataSet.each(function(line){
			line.removeOption = true;
		});
	},
	addMoveOption:function() {
		this.moveOptionEnabled = true;
	},
	removeItem:function(index, callEvent) {
		Element.remove(this.dataSet[index].node);
		this.dataSet.splice(index,1);
		this._updateIndexes();
		if (callEvent || callEvent==null) this.onRemove(index);
	},
	removeAll:function() {
		while(this.dataSet.length>0)
			this.removeItem(this.dataSet.length-1);
	},
	clear:function() {
		while(this.dataSet.length>0) {
			var index = this.dataSet.length-1;
			Element.remove(this.dataSet[index].node);
			this.dataSet.splice(index,1);
		}
		this._updateIndexes();
	},
	moveItem:function(direction, index) {
		if (direction==-1) {
			if (index>0) {
				var node = this.dataSet[index].node;
				var previousNode = this.dataSet[index-1].node;
				node.parentNode.insertBefore(node, previousNode);
				var previousSet = this.dataSet[index-1];
				this.dataSet[index-1] = this.dataSet[index];
				this.dataSet[index] = previousSet;
				this._updateIndexes();
				this.onMove(direction, index);
			}
		} else if (direction==1) {
			if (index<(this.dataSet.length-1)) {
				var node = this.dataSet[index].node;
				var nextNode = this.dataSet[index+1].node;
				node.parentNode.insertBefore(nextNode, node);
				var nextSet = this.dataSet[index+1];
				this.dataSet[index+1] = this.dataSet[index];
				this.dataSet[index] = nextSet;
				this._updateIndexes();
				this.onMove(direction, index);
			}
		}
	},
	onRemove:function() {},
	onBeforeRemove:function() {},
	onMove:function() {},
	_setItemDragEvents:function(line) {
		line.node.style.cursor = "move";
		var originalBackground = Element.getStyle(line.node, 'background-color');
		line.node.onmouseover = function() {
			this.style.backgroundColor = "lightyellow";
		}
		line.node.onmouseout = function() {
			this.style.backgroundColor = originalBackground;
		}
		line.node.onmousedown = function(e) {
			var e = e || window.event;
			var div = this.cloneNode(true);	
			div.style.position = "absolute";
			div.className = "dgDragItem";
			div.style.backgroundColor = "#FFF";
			div.style.border = "1px solid #C5D5FC";
			div.lineData = line;
			document.body.appendChild(div);
			Position.clone(this, div);
			var drag = new Draggable(div, {revert:true, endRevertEffect:function() {
				try{Element.remove(div);}catch(e){};
			}});
			drag.initDrag(e);
			drag.startDrag(e);
		}
	},
	enableItemDrag:function(enable) {
		var self = this;
		this.dataSet.each(function(line){
			if (enable) {
				self._setItemDragEvents(line);
			}			
		});
	},
	enableItemDrop:function(enable) {
		var self = this;
		this.dataSet.each(function(item, index){
			Droppables.add(item.node, {accept:'dgDragItem', onDrop:function(node){
				self.onItemDrop(node.onBoardData, {datagrid:self,itemIndex:index});
				Element.remove(node);
			},hoverclass:'dgItemOnDragOver', noPositionChange:true});
		});
	},	
	render:function() {
		this.domNode.innerHTML = "";
		this.domNode.appendChild(this.table);
	}
};

Math.roundNum = function(n,p) {
	var t = Math.pow(10,p);
	return Math.round(n*t)/t;
}

Element.addMethods({  
  getInnerText: function(element) {
    element = $(element);
    return element.innerText && !window.opera ? element.innerText
      : element.innerHTML.stripScripts().unescapeHTML().replace(/[\n\r\s]+/g, ' ');
  }
});
