/**
 * @projectDescription 	asolib.js / a tiny lightweight javascript library
 * @author		Amin Ladhani / amin@as-o.ch / 2010
 * @version		0.2
 */

/* -----------------------------------------------------------------------------------------
Les librairies asolib.js et asolib.basicfx.js sont la propriété de Amin Ladhani
mais peuvent être utilisées par des tiers moyennant une demande expresse faite
par mail, par téléphone ou de vive voix à l'auteur. De plus, le nom et l'email
de l'auteur ainsi que la version des scripts doivent être mentionnés soit directement
dans les pages de scripts soit quelque part dans les sites où ces derniers sont utilisés.
----------------------------------------------------------------------------------------- */

/* -----------------------------------------------------------------------------------------
Les librairies asolib.js et asolib.basicfx.js ont été testés avec succès sur les navigateurs
suivants :
- Firefox 3.6+
- Safari 4 +
- Google Chrome 6+
- Internet Explorer 6, 7, 8 et 9
Il est possible que des problèmes surviennent avec les versions antérieures des navigateurs
mentionnés ci-dessus.
----------------------------------------------------------------------------------------- */

(function () {
		var _lib = {
			_domExtend : function (obj) {
				for (method in obj) {
					if (window._browser().isIE6 || window._browser().isIE7)
						document[method] = obj[method];
					if (window._browser().isIE8)
						HTMLDocument.prototype[method] = obj[method];
					if (!window._browser().isIE || window._browser().isIE9)
						HTMLElement.prototype[method] = obj[method]
				}
			},
			_ieDomExtend : function (el, extend) {
				if (!window._browser().isIE || window._browser().isIE9)
					return false;
				if (el && el.length)
					for (var i = 0; i < el.length; i++)
						for (method in extend)
							el[i][method] = extend[method];
				else
					for (method in extend)
						if (el)
							el[method] = extend[method]
			},
			_browser : function () {
				var toString = Object.prototype.toString,
				ua = navigator.userAgent.toLowerCase(),
				check = function (r) {
					return r.test(ua)
				},
				isOpera = check(/opera/),
				isChrome = check(/\bchrome\b/),
				isWebKit = check(/webkit/),
				isSafari = !isChrome && check(/safari/),
				isSafari2 = isSafari && check(/applewebkit\/4/),
				isSafari3 = isSafari && check(/version\/3/),
				isSafari4 = isSafari && check(/version\/4/),
				isIE = !isOpera && check(/msie/),
				isIE7 = isIE && check(/msie 7/),
				isIE8 = isIE && check(/msie 8/),
				isIE9 = isIE && check(/msie 9/),
				isIE6 = isIE && !isIE7 && !isIE8 && !isIE9,
				isGecko = !isWebKit && check(/gecko/),
				isGecko2 = isGecko && check(/rv:1\.8/),
				isGecko3 = isGecko && check(/rv:1\.9/),
				isWindows = check(/windows|win32/),
				isMac = check(/macintosh|mac os x/),
				isLinux = check(/linux/);
				return {
					isOpera : isOpera,
					isChrome : isChrome,
					isWebKit : isWebKit,
					isSafari : isSafari,
					isSafari2 : isSafari2,
					isSafari3 : isSafari3,
					isSafari4 : isSafari4,
					isIE : isIE,
					isIE6 : isIE6,
					isIE7 : isIE7,
					isIE8 : isIE8,
					isIE9 : isIE9,
					isGecko : isGecko,
					isGecko2 : isGecko2,
					isGecko3 : isGecko3,
					isWindows : isWindows,
					isMac : isMac,
					isLinux : isLinux
				}
			},
			_addEvent : function (obj, type, fn) {
				(obj.addEventListener) ? obj.addEventListener(type, fn, false) : obj.attachEvent("on" + type, fn)
			},
			_removeEvent : function (obj, type, fn) {
				(obj.removeEventListener) ? obj.removeEventListener(type, fn, false) : obj.detachEvent("on" + type, fn)
			},
			_cancelDefaultEvent : function (e) {
				e = e || window.event;
				if (e.preventDefault && e.stopPropagation) {
					e.preventDefault();
					e.stopPropagation()
				}
				return false
			},
			_noSelect : function (element) {
				if (element.setAttribute && element.nodeName.toLowerCase() != 'input' && element.nodeName.toLowerCase() != 'textarea')
					element.setAttribute('unselectable', 'on');
				for (var i = 0; i < element.childNodes.length; i++)
					_lib._noSelect(element.childNodes[i])
			},
			_camelize : function (s) {
				return s.replace(/\-(.)/g, function (j, k) {
						return k.toUpperCase()
					})
			},
			_getMousePos : function (e) {
				e = window.event ? window.event : e;
				var pos = {};
				pos.x = e.clientX;
				pos.y = e.clientY;
				return pos
			},
			_getSize : function () {
				var s = {};
				s.x = document.documentElement.clientWidth;
				s.y = document.documentElement.clientHeight;
				return s
			},
			_getTime : function () {
				return new Date().getTime()
			},
			_each : function (fn, bind) {
				for (var key in this)
					if (key != '_each')
						fn.call(bind, this[key], key, this)
			},
			_walk : function (fn, bind) {
				for (var i = 0; i < this.length; i++)
					fn.call(bind, this[i], i, this)
			},
			_implement : function (trg, o, proto) {
				if (proto)
					for (var i in o)
						trg.prototype[i] = o[i];
				else
					for (var i in o)
						trg[i] = o[i]
			},
			_strToInt : function (str) {
				return parseInt(str.toString().replace(/[^0-9]/g, ''))
			},
			_domReady : function (callback) {
				if (document.addEventListener)
					try {
						document.addEventListener("DOMContentLoaded", callback, false)
					} catch (e) {}
					
				else {
					(function () {
							if (!document.uniqueID && document.expando)
								return;
							var tempNode = document.createElement('document:ready');
							try {
								tempNode.doScroll('left');
								callback();
								tempNode = null
							} catch (err) {
								setTimeout(arguments.callee, 0)
							}
						})()
				}
			}
		};
		window._browser = _lib._browser;
		window._getMousePos = _lib._getMousePos;
		window._getWindowSize = _lib._getSize;
		window._onDomReady = _lib._domReady;
		_main = _lib;
		_DOMExtend = _lib._domExtend;
		var _framework = {
			_element : function (el, d) {
				if (typeof el === "string")
					el = (d || document).createElement(el);
				_lib._ieDomExtend(el, _framework);
				return el
			},
			_implement : function (o) {
				_lib._implement(this, o);
				return this
			},
			_getById : function (id) {
				if (typeof id === 'string') {
					var el = document.getElementById(id);
					_lib._ieDomExtend(el, _framework);
					return el
				}
			},
			_getByTagName : function (tag) {
				if (typeof tag === 'string') {
					var els = this.getElementsByTagName(tag);
					_lib._ieDomExtend(els, _framework);
					els._each = _lib._walk;
					return els
				}
			},
			_getByClassName : function (name) {
				if (typeof name === 'string') {
					var e = this._getByTagName('*'),
					arr = [];
					for (var i = 0; i < e.length; i++) {
						if (e[i].className == name) {
							_lib._ieDomExtend(e[i], _framework);
							arr.push(e[i])
						}
					}
					return arr
				}
			},
			_appendTo : function (el) {
				el.appendChild(this);
				return this
			},
			_appendBefore : function (el) {
				el.parentNode.insertBefore(this, el);
				return this
			},
			_removeElement : function () {
				this.parentNode.removeChild(this)
			},
			_setHtml : function (h) {
				this.innerHTML = h;
				return this
			},
			_getHtml : function () {
				return this.innerHTML
			},
			_addEvent : function (type, fn) {
				_lib._addEvent(this, type, fn);
				return this
			},
			_removeEvent : function (type, fn) {
				_lib._removeEvent(this, type, fn);
				return this
			},
			_getPosition : function () {
				var curleft = curtop = 0;
				var o = obj = this;
				var pos = {};
				if (obj.offsetParent) {
					do {
						curleft += obj.offsetLeft;
						curtop += obj.offsetTop
					} while (obj = obj.offsetParent)
				}
				var b = (!window.opera) ? _lib._strToInt(this._getStyle('border-width')) || _lib._strToInt(this.style.border) || 0 : 0;
				pos.x = curleft + b;
				pos.y = curtop + b;
				return pos
			},
			_getSize : function () {
				var w = this.offsetWidth;
				var h = this.offsetHeight;
				return {
					'width' : w,
					'height' : h
				}
			},
			_noSelect : function () {
				_lib._noSelect(this);
				return this
			},
			_selectOff : function (cursor) {
				if (cursor)
					this.style.cursor = cursor;
				this.onselectstart = function () {
					return false
				};
				this.onmousedown = function () {
					return false
				}
			},
			_selectOn : function () {
				this.style.cursor = '';
				this.onselectstart = function () {
					return
				};
				this.onmousedown = function () {
					return
				}
			},
			_getParent : function (tag) {
				var el = this;
				do {
					if (el && el.nodeName && el.nodeName.toUpperCase() == tag) {
						return el
					}
					el = el.parentNode
				} while (el);
				return false
			},
			_setClass : function (cls) {
				this.className = cls;
				return this
			},
			_addClass : function (cls) {
				this.className = this.className + ' ' + cls;
				return this
			},
			_removeClass : function (cls) {
				this.className = this.className.replace(cls, '');
				return this
			},
			_style : function (r, v) {
				var elStyle = this.style,
				v = v.toString().replace(/px/, ''),
				e = !r.match(/opacity|color/) ? 'px' : '';
				switch (r) {
				case 'float':
					elStyle['cssFloat'] = elStyle['styleFloat'] = v;
					break;
				case 'opacity':
					elStyle['opacity'] = v / 100;
					elStyle.filter = "alpha(opacity=" + Math.round(v) + ")";
					break;
				default:
					try {
						elStyle[_lib._camelize(r)] = v + e
					} catch (e) {}
					
				}
				return this
			},
			_setStyle : function (st) {
				var elStyle = this.style;
				for (var itm in st) {
					switch (itm) {
					case 'float':
						elStyle['cssFloat'] = elStyle['styleFloat'] = st[itm];
						break;
					case 'opacity':
						elStyle.opacity = st[itm];
						elStyle.filter = "alpha(opacity=" + Math.round(st[itm] * 100) + ")";
						break;
					case 'className':
						this.className = st[itm];
						break;
					default:
						elStyle[_lib._camelize(itm)] = st[itm]
					}
				}
				return this
			},
			_getStyle : function (cssRule, d) {
				var doc = (!d) ? document.defaultView : d;
				if (this.nodeType == 1) {
					return (doc && doc.getComputedStyle) ? doc.getComputedStyle(this, null).getPropertyValue(cssRule) : this.currentStyle[_lib._camelize(cssRule)]
				}
			},
			_removeStyle : function () {
				for (var i = 0; i < arguments.length; i++)
					this.style[_lib._camelize(arguments[i])] = '';
				return this
			},
			_setAttributes : function (at) {
				for (var item in at)
					this[item] = at[item];
				return this
			},
			_removeAttributes : function () {
				for (var i = 0; i < arguments.length; i++)
					this[arguments[i]] = '';
				return this
			}
		};
		document._getById = document.getElementById;
		document._getById = _framework._getById;
		document._getByClassName = _framework._getByClassName;
		document._getByTagName = _framework._getByTagName;
		_DOMExtend(_framework);
		_element = _framework._element;
		_lib._implement(Array, {
				_each : function (fn, bind) {
					for (var i = 0, l = this.length; i < l; i++)
						fn.call(bind, this[i], i, this)
				},
				_inArray : function (array, item) {
					for (var i = 0; i < array.length; i++) {
						if (array[i] == item)
							return i
					}
				},
				_replace : function () {},
				_move : function () {}
				
			}, true);
		var _server = {
			_httpRequest : {
				get : function (o) {
					this.req = _server._httpRequest.request;
					this.req(o);
					this.xhr.open("get", this.file + this.param);
					this.xhr.send(null);
					return this
				},
				post : function (o) {
					this.req = _server._httpRequest.request;
					this.req(o);
					this.xhr.open("post", this.file, true);
					this.xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
					this.xhr.send(this.param);
					return this
				},
				request : function (o) {
					if (!o['file'])
						return false;
					var self = this;
					_lib._implement(this, o);
					this.responseText = null;
					this.xhr = window._browser().isIE6 ? new ActiveXObject("Microsoft.xmlhttp") : new XMLHttpRequest();
					if (this.onSend)
						this.onSend();
					this.xhr.onreadystatechange = function () {
						if (self.xhr.readyState == 4) {
							if (self.xhr.status == 200) {
								self.responseText = self.xhr.responseText;
								if (self.onReceive != null)
									self.onReceive()
							}
						}
					}
				}
			},
			_form : function () {}
			
		};
		_httpRequest = _request = _ajax = _server._httpRequest;
		_createForm = _server._form;
		var _json = {
			encode : function (o) {
				if (typeof o != 'object')
					return false;
				var walk = function (o) {
					var string = '',
					l,
					j;
					for (var j in o)
						l = j;
					for (i in o) {
						if (typeof o[i] == 'object') {
							if (o[i]instanceof Array) {
								for (j = 0, string += '"' + i + '":['; j < o[i].length; j++)
									string += (j > 0 ? ',' : '') + '"' + o[i][j] + '"';
								string += i == l ? ']' : '],'
							} else {
								var c = i == l ? '}' : '},';
								string += '"' + i + '":{';
								string += walk(o[i]);
								string += c
							}
						} else {
							string += '"' + i + '":"' + o[i] + (i == l ? '"' : '",')
						}
					}
					return string
				};
				string = walk(o);
				return '{' + string + '}'
			},
			parse : function (s) {
				try {
					return eval('(' + s + ')')
				} catch (ex) {}
				
			}
		};
		_jsonEncode = _json.encode;
		_jsonParse = _json.parse;
		var _cook = {
			writeCookie : function (name, value, days) {
				if (days) {
					var date = new Date();
					date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
					var expires = "; expires=" + date.toGMTString()
				} else
					var expires = "";
				document.cookie = name + "=" + value + expires + "; path=/"
			},
			readCookie : function (name) {
				var nameEQ = name + "=";
				var ca = document.cookie.split(';');
				for (var i = 0; i < ca.length; i++) {
					var c = ca[i];
					while (c.charAt(0) == ' ')
						c = c.substring(1, c.length);
					if (c.indexOf(nameEQ) == 0)
						return c.substring(nameEQ.length, c.length)
				}
				return null
			},
			delCookie : function (name) {
				createCookie(name, "", -1)
			}
		};
		_cook.manager = function (cookie, days) {
			this.cookie = cookie;
			if (!_cook.readCookie(this.cookie)) {
				_cook.writeCookie(this.cookie, days)
			}
		};
		_cook.manager.prototype.load = function () {
			var ck;
			this.ck = {};
			try {
				this.ck_loaded = _cook.readCookie(this.cookie).split(';');
				if (this.ck_loaded) {
					for (ck in this.ck_loaded) {
						if (typeof this.ck_loaded[ck] != 'string')
							continue;
						var _ck = this.ck_loaded[ck].split('=');
						this.ck[_ck[0]] = _ck[1]
					}
				}
			} catch (e) {}
			
		};
		_cook.manager.prototype.getname = function () {
			return this.cookie
		};
		_cook.manager.prototype.get = function (ck_fragment) {
			this.load();
			return this.ck[ck_fragment]
		};
		_cook.manager.prototype.set = function (ck_fragment, ck_value) {
			this.load();
			this.ck[ck_fragment] = ck_value;
			this.save()
		};
		_cook.manager.prototype.remove = function (ck_fragment) {
			this.load();
			this.ck[ck_fragment] = '';
			this.save()
		};
		_cook.manager.prototype.count = function () {
			var j = 0;
			for (i in this.ck)
				j++;
			return j
		};
		_cook.manager.prototype.show = function () {
			this.load();
			var i,
			str_ck = '';
			for (i in this.ck)
				if (i)
					str_ck += i + " : " + this.ck[i] + "\n";
			alert(str_ck)
		};
		_cook.manager.prototype.save = function () {
			var str_ck = '',
			pr,
			i = 1,
			sep = '',
			num = this.count();
			for (pr in this.ck) {
				if (!this.ck[pr])
					continue;
				str_ck += pr + "=" + this.ck[pr];
				str_ck += i == num ? '' : ';';
				i++
			}
			_cook.writeCookie(this.cookie, str_ck)
		};
		_cook.manager.prototype.deletecookie = function () {
			_cook.delCookie(this.cookie)
		};
		_cookie = _cook;
		_cookieManager = _cook.manager;
		_lib._implement(_framework, {
				_setSelectedIndex : function (value) {
					if (this.tagName != 'SELECT')
						return false;
					var opt = this.getElementsByTagName('option');
					for (var i = 0; i < opt.length; i++)
						if (opt[i].value == value)
							opt[i].selected = 'selected'
				},
				_getSelectedValue : function (type) {
					if (this.tagName != 'SELECT')
						return false;
					var opt = this.getElementsByTagName('option');
					for (var i = 0; i < opt.length; i++)
						if (opt[i].selected)
							var selectedValue = opt[i].getAttribute(type);
					return selectedValue
				},
				_saveScrollPos : function (cookie, ckName) {
					var _this = this;
					if (cookie._get(ckName)) {
						this.scrollTop = parseInt(cookie._get(ckName))
					}
					this.onscroll = function () {
						cookie.set(ckName, _this.scrollTop)
					};
					if (!document.all) {
						this.addEventListener('DOMMouseScroll', function () {
								cookie.set(ckName, _this.scrollTop)
							}, false)
					}
				},
				_getType : function () {
					alert(typeof this)
				}
			})
	})();
 
