/* Classe Core */
/**
 * Extension de la classe Array
 * @author 58062
 * @from php.js
 */

function ExtObj(){};
/**
 * Check if value exist in the array
 * @param {Object} needle : the value searched
 * @param {Object} strict optionnal |true| if you want to check the type
 * @return {Bool}
 */
ExtObj.has = function (obj, needle, strict) {
		var found = false, key, strict = !!strict;
		for (key in obj) {
		  if ((strict && obj[key] === needle) || (!strict && obj[key] == needle)) {
		      found = true;
		      break;
		  }
		}
	 	return found;
	};
/**
 * Checks if the given key or index exists in the array
 * @param {Object} key
 * @return {Bool}
 */
ExtObj.keyExists =  function (obj, key ) {
	    // input sanitation
	    if( !obj || (obj.constructor !== Array && obj.constructor !== Object) )
	        return false;
	
	    return key in obj;
	};
Array.implement({
	has: function (needle, strict) {
		return ExtObj.has(this, needle, strict);
	},
	keyExists: function ( key ) {
	    return ExtObj.keyExists(this, key);
	}
});
/**
 * Extension de l'objet Natif Date
 */
Date.implement ({
	/**
	 * Validate a Gregorian date
	 * @param {Int} month
	 * @param {Int} day
	 * @param {Int} year
	 *     example 1: checkdate(12, 31, 2000);
	 *     returns 1: true
	 *     example 2: checkdate(2, 29, 2001);
	 *     returns 2: false
	 *     example 3: checkdate(03, 31, 2008);
	 *     returns 3: true
	 *     example 4: checkdate(1, 390, 2000);
	 *     returns 4: false
	 */
	checkdate: function ( month, day, year ) {
	   var myDate = new Date();
	    myDate.setFullYear( year, (month - 1), day );

	    return ((myDate.getMonth()+1) == month && day<32);
	},

	/**
	 * Format a local time/date
	 * @param {Object} format
	 * @param {Object} timestamp
	 *     example 1: Date.format('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
	 *     returns 1: '09:09:40 m is month'
	 *     example 2: Date.format('F j, Y, g:i a', 1062462400);
	 *     returns 2: 'September 2, 2003, 2:26 am'
	 */
	format: function ( formatType, timestamp ) {


	    var a, jsdate=((timestamp) ? new Date(timestamp*1000) : new Date());
	    var pad = function(n, c){
	        if( (n = n + "").length < c ) {
	            return new Array(++c - n.length).join("0") + n;
	        } else {
	            return n;
	        }
	    };
	    var txt_weekdays = ["Sunday","Monday","Tuesday","Wednesday",
	        "Thursday","Friday","Saturday"];
	    var txt_ordin = {1:"st",2:"nd",3:"rd",21:"st",22:"nd",23:"rd",31:"st"};
	    var txt_months =  ["", "January", "February", "March", "April",
	        "May", "June", "July", "August", "September", "October", "November",
	        "December"];

	    var f = {
	        // Day
	            d: function(){
	                return pad(f.j(), 2);
	            },
	            D: function(){
	                t = f.l(); return t.substr(0,3);
	            },
	            j: function(){
	                return jsdate.getDate();
	            },
	            l: function(){
	                return txt_weekdays[f.w()];
	            },
	            N: function(){
	                return f.w() + 1;
	            },
	            S: function(){
	                return txt_ordin[f.j()] ? txt_ordin[f.j()] : 'th';
	            },
	            w: function(){
	                return jsdate.getDay();
	            },
	            z: function(){
	                return (jsdate - new Date(jsdate.getFullYear() + "/1/1")) / 864e5 >> 0;
	            },

	        // Week
	            W: function(){
	                var a = f.z(), b = 364 + f.L() - a;
	                var nd2, nd = (new Date(jsdate.getFullYear() + "/1/1").getDay() || 7) - 1;

	                if(b <= 2 && ((jsdate.getDay() || 7) - 1) <= 2 - b){
	                    return 1;
	                } else{

	                    if(a <= 2 && nd >= 4 && a >= (6 - nd)){
	                        nd2 = new Date(jsdate.getFullYear() - 1 + "/12/31");
	                        return date("W", Math.round(nd2.getTime()/1000));
	                    } else{
	                        return (1 + (nd <= 3 ? ((a + nd) / 7) : (a - (7 - nd)) / 7) >> 0);
	                    }
	                }
	            },

	        // Month
	            F: function(){
	                return txt_months[f.n()];
	            },
	            m: function(){
	                return pad(f.n(), 2);
	            },
	            M: function(){
	                t = f.F(); return t.substr(0,3);
	            },
	            n: function(){
	                return jsdate.getMonth() + 1;
	            },
	            t: function(){
	                var n;
	                if( (n = jsdate.getMonth() + 1) == 2 ){
	                    return 28 + f.L();
	                } else{
	                    if( n & 1 && n < 8 || !(n & 1) && n > 7 ){
	                        return 31;
	                    } else{
	                        return 30;
	                    }
	                }
	            },

	        // Year
	            L: function(){
	                var y = f.Y();
	                return (!(y & 3) && (y % 1e2 || !(y % 4e2))) ? 1 : 0;
	            },
	            //o not supported yet
	            Y: function(){
	                return jsdate.getFullYear();
	            },
	            y: function(){
	                return (jsdate.getFullYear() + "").slice(2);
	            },

	        // Time
	            a: function(){
	                return jsdate.getHours() > 11 ? "pm" : "am";
	            },
	            A: function(){
	                return f.a().toUpperCase();
	            },
	            B: function(){
	                // peter paul koch:
	                var off = (jsdate.getTimezoneOffset() + 60)*60;
	                var theSeconds = (jsdate.getHours() * 3600) +
	                                 (jsdate.getMinutes() * 60) +
	                                  jsdate.getSeconds() + off;
	                var beat = Math.floor(theSeconds/86.4);
	                if (beat > 1000) beat -= 1000;
	                if (beat < 0) beat += 1000;
	                if ((String(beat)).length == 1) beat = "00"+beat;
	                if ((String(beat)).length == 2) beat = "0"+beat;
	                return beat;
	            },
	            g: function(){
	                return jsdate.getHours() % 12 || 12;
	            },
	            G: function(){
	                return jsdate.getHours();
	            },
	            h: function(){
	                return pad(f.g(), 2);
	            },
	            H: function(){
	                return pad(jsdate.getHours(), 2);
	            },
	            i: function(){
	                return pad(jsdate.getMinutes(), 2);
	            },
	            s: function(){
	                return pad(jsdate.getSeconds(), 2);
	            },
	            //u not supported yet

	        // Timezone
	            //e not supported yet
	            //I not supported yet
	            O: function(){
	               var t = pad(Math.abs(jsdate.getTimezoneOffset()/60*100), 4);
	               if (jsdate.getTimezoneOffset() > 0) t = "-" + t; else t = "+" + t;
	               return t;
	            },
	            P: function(){
	                var O = f.O();
	                return (O.substr(0, 3) + ":" + O.substr(3, 2));
	            },
	            //T not supported yet
	            //Z not supported yet

	        // Full Date/Time
	            c: function(){
	                return f.Y() + "-" + f.m() + "-" + f.d() + "T" + f.h() + ":" + f.i() + ":" + f.s() + f.P();
	            },
	            //r not supported yet
	            U: function(){
	                return Math.round(jsdate.getTime()/1000);
	            }
	    };

	    return formatType.replace(/[\\]?([a-zA-Z])/g, function(t, s){
	        if( t!=s ){
	            // escaped
	            ret = s;
	        } else if( f[s] ){
	            // a date function exists
	            ret = f[s]();
	        } else{
	            // nothing special
	            ret = s;
	        }

	        return ret;
	    });
	}
});

function Display(){}
/**
 * Retourne la position absolue en ordonn�e d'un element
 * @param  (Object) oElement: 		element dont l'on cherche la position en X
 * @return (int)		iReturnValue: position en X
 */
Display.getY = function (oElement){
		var iReturnValue = 0;

		while( oElement != null ) {
			iReturnValue += oElement.offsetTop;
			oElement = oElement.offsetParent;
		}

		return iReturnValue;
	};
/**
 * Retourne la position absolue en abscisse d'un element
 * @param  (Object) oElement: 		element dont l'on cherche la position en Y
 * @return (int)		iReturnValue: position en Y
 */
Display.getX = function (oElement){
		var iReturnValue = 0;

		while( oElement != null ){
			iReturnValue += oElement.offsetLeft;
			oElement = oElement.offsetParent;
		}

	return iReturnValue;
};

/**
 * Extension de l'objet Number
 */
Number.implement({

	dechex: function() {
		// Returns a string containing a hexadecimal representation of the given number
		//
		// version: 906.1806
		// discuss at: http://phpjs.org/functions/dechex
		// +   original by: Philippe Baumann
		// +   bugfixed by: Onno Marsman
		// +   improved by: http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript
		// +   input by: pilus
		// *     example 1: dechex(10);
		// *     returns 1: 'a'
		// *     example 2: dechex(47);
		// *     returns 2: '2f'
		// *     example 3: dechex(-1415723993);
		// *     returns 3: 'ab9dc427'
		if (this < 0) {
		   return (0xFFFFFFFF+this+1).toString(16);
		}
		return parseInt(this, 10).toString(16);
	}

});
/**
 * Extension de l'objet String
 */
String.implement({

	/**
	 * Check if the String is correct E-mail adress
	 * @return (Boolean)
	 */
	isEmail: function () {
		var verif = /^[a-zA-Z0-9]([-_.]?[0-9a-zA-Z])+@[a-zA-Z0-9-]{2,}[.][a-zA-Z]{2,3}$/;
		if (verif.exec(this) == null)
			return false;
		else
			return true;
	},

	/**
	 * Transform first char of each word in a string to uppercase
	 */
	ucwords: function () {
		return this.replace(/^(.)|\s(.)/g, function ( $1 ) { return $1.toUpperCase ( ); } );
	},

	/**
	 * Strip whitespace (or other characters) from the beginning and end of a string
	 */
	trim: function () {
	  return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
	},

	
	/**
	 * Return part of a string
	 * @param {Object} f_start
	 * @param {Object} f_length
	 *       example 1:	str = 'abcdef';
	 *       			str.substr(0, -1);
	 *       returns 1: 'abcde'
	 *       example 2: str = 2;
	 *       			str.substr(0, -6);
	 *       returns 2: ''
	 */
	substr: function ( f_start, f_length ) {
	    f_string = this+'';

	    if(f_start < 0) {
	        f_start += f_string.length;
	    }

	    if(f_length == undefined) {
	        f_length = f_string.length;
	    } else if(f_length < 0){
	        f_length += f_string.length;
	    } else {
	        f_length += f_start;
	    }

	    if(f_length < f_start) {
	        f_length = f_start;
	    }

	    return f_string.substring(f_start, f_length);
	}
});
