/**
* ÃÖÀûÈ­(¿ÀÃ¢ÈÆ) 2008-03-28
*/
var $cache_mode = true;

var Class = function(properties){
	var klass = function(){
		for (p in this) this[p]._proto_ = this;
		if (arguments[0] != 'noinit' && this.initialize) return this.initialize.apply(this, arguments);
	};
	klass.extend = this.extend;
	klass.implement = this.implement;
	klass.prototype = properties;
	return klass;
};

Class.empty = function(){};

Class.create = function(properties){
	return new Class(properties);
};

Class.prototype = {
	extend: function(properties){
		var prototype = new this('noinit');
		for (property in properties){
			var previous = prototype[property];
			var current = properties[property];
			if (previous && previous != current) current = previous.parentize(current) || current;
			prototype[property] = current;
		}
		return new Class(prototype);
	},

	implement: function(properties){
		for (property in properties) this.prototype[property] = properties[property];
	}
}


var getClient ={
	init : function(){
		var userAgent = navigator.userAgent.toLowerCase();
		var browser = {IE : /msie/.test(userAgent),FF :/gecko/.test(userAgent),OP:/opera/.test(userAgent)};
		for(var prop in browser){if(browser[prop]){this.agent = prop;break;}}
		if(this.agent == "")this.agent = "IE";
	}
};
getClient.init();

var EventManager = {
	addEvent: function(el,action, fn){
		el[action+fn] = fn.bind(el);
		if (el.addEventListener) el.addEventListener(action, fn, false);
		else el.attachEvent('on'+action, el[action+fn]);

		var _el = this;
		if (el != window) Unload.functions.push(function(){
			_el.removeEvent(el,action, fn);
			_el[action+fn] = null;
		});
		return el;
	},
	removeEvent: function(el,action, fn){
		try{
			if (el.removeEventListener) el.removeEventListener(action, fn, false);
			else el.detachEvent('on'+action, el[action+fn]);
			return el;
		}catch(e){
		}
	}
}


Object.extend = function(){
	var args = arguments;
	if (args[1]) args = [args[0], args[1]];
	else args = [this, args[0]];
	for (property in args[1]) args[0][property] = args[1][property];
	return args[0];
};

Object.Native = function(){
	for (var i = 0; i < arguments.length; i++) arguments[i].extend = Class.prototype.implement;
};

new Object.Native(Function, Array, String);

Function.extend({
	parentize: function(current){
		var previous = this;
		return function(){
			this.parent = previous;
			return current.apply(this, arguments);
		};
	}
});


Function.extend({

	pass: function(args, bind){
		var fn = this;
		if ($type(args) != 'array') args = [args];
		return function(){
			fn.apply(bind || fn._proto_ || fn, args);
		};
	},

	bind: function(bind){
		var fn = this;
		return function(){
			return fn.apply(bind, arguments);
		};
	},

	bindAsEventListener: function(bind){
		var fn = this;
		return function(event){
			fn.call(bind, event || window.event);
			return false;
		};
	},

	delay: function(ms, bind){
		return setTimeout(this.bind(bind || this._proto_ || this), ms);
	},

	periodical: function(ms, bind){
		return setInterval(this.bind(bind || this._proto_ || this), ms);
	}

});

function $clear(timer){
	clearTimeout(timer);
	clearInterval(timer);
	return null;
};


function $type(obj, type){

	if (!obj) return false;
	var type = false;

	if (obj instanceof Function) type = 'function';
	else if (obj.nodeName){
		if (obj.nodeType == 3 && !/\S/.test(obj.nodeValue)) type = 'textnode';
		else if (obj.nodeType == 1) type = 'element';
	}
	else if (obj instanceof Array) type = 'array';
	else if (typeof obj == 'object') type = 'object';
	else if (typeof obj == 'string') type = 'string';
	else if (typeof obj == 'number' && isFinite(obj)) type = 'number';
	return type;
};


function $check(obj, objTrue, objFalse){
	if (obj) {
		if (objTrue && $type(objTrue) == 'function') return objTrue();
		else return objTrue || obj;
	} else {
		if (objFalse && $type(objFalse) == 'function') return objFalse();
		return objFalse || false;
	}
};

var Chain = new Class({
	chain: function(fn){
		this.chains = this.chains || [];
		this.chains.push(fn);
		return this;
	},
	callChain: function(){
		if (this.chains && this.chains.length) this.chains.splice(0, 1)[0].delay(10, this);
	}

});


if (!Array.prototype.forEach){
	Array.prototype.forEach = function(fn, bind){
		for(var i = 0; i < this.length ; i++) fn.call(bind, this[i], i);
	};
}

Array.extend({
	each: Array.prototype.forEach,
	copy: function(){
		var nArray = [];
		for (var i = 0; i < this.length; i++) nArray.push(this[i]);
		return nArray;
	},
	remove: function(item){
		for (var i = 0; i < this.length; i++){
			if (this[i] == item) this.splice(i, 1);
		}
		return this;
	},
	test: function(item){
		for (var i = 0; i < this.length; i++){
			if (this[i] == item) return true;
		};
		return false;
	},
	extend: function(nArray){
		for (var i = 0; i < nArray.length; i++) this.push(nArray[i]);
		return this;
	}

});

function $A(array){
	return Array.prototype.copy.call(array);
};


String.extend({
	test: function(value, params){
		return this.match(new RegExp(value, params));
	},
	camelCase: function(){
		return this.replace(/-\D/gi, function(match){
			return match.charAt(match.length - 1).toUpperCase();
		});
	},
	capitalize: function(){
		return this.toLowerCase().replace(/\b[a-z]/g, function(match){
			return match.toUpperCase();
		});
	},
	trim: function(){
		return this.replace(/^\s*|\s*$/g,'');
	},
	clean: function(){
		return this.replace(/\s\s/g, ' ').trim();
	},
	endsWith : function endsWith(c){
		if(this.charAt(this.length - 1) == c){
			return true;
		} else {
			return false;
		}
	},
	startsWith : function startsWith(c){
		if(this.charAt(0) == c){
			return true;
		} else {
			return false;
		}
	},
	replaceAll : function replaceAll(a, b){
		var s = this;
		while(s.indexOf(a) > -1){
			s = s.replace(a, b);
		}
		return s;
	},
	rgbToHex: function(array){
		var rgb = this.test('^[rgba]{3,4}\\(([\\d]{0,3}),[\\s]*([\\d]{0,3}),[\\s]*([\\d]{0,3})\\)$');
		var hex = [];
		for (var i = 1; i < rgb.length; i++) hex.push((rgb[i]-0).toString(16));
		var hexText = '#'+hex.join('');
		if (array) return hex;
		else return hexText;
	},

	hexToRgb: function(array){
		var hex = this.test('^[#]{0,1}([\\w]{1,2})([\\w]{1,2})([\\w]{1,2})$');
		var rgb = [];
		for (var i = 1; i < hex.length; i++){
			if (hex[i].length == 1) hex[i] += hex[i];
			rgb.push(parseInt(hex[i], 16));
		}
		var rgbText = 'rgb('+rgb.join(',')+')';
		if (array) return rgb;
		else return rgbText;
	}
});

var Element = new Class({
	initialize: function(el){
		if ($type(el) == 'string') el = document.createElement(el);
		return $(el);
	},
	inject: function(el, where){
		var el = $check($(el), $(el), new Element(el));
		switch(where){
			case "before": $(el.parentNode).insertBefore(this, el); break;
			case "after": {
					if (!el.getNext()) $(el.parentNode).appendChild(this);
					else $(el.parentNode).insertBefore(this, el.getNext());
			} break;
			case "inside": el.appendChild(this); break;
		}
		return this;
	},
	injectBefore: function(el){
		return this.inject(el, 'before');
	},
	injectAfter: function(el){
		return this.inject(el, 'after');
	},
	injectInside: function(el){
		return this.inject(el, 'inside');
	},
	adopt: function(el){
		var el = $check($(el), $(el), new Element(el));
		this.appendChild(el);
		return this;
	},
	remove: function(){
		this.parentNode.removeChild(this);
	},
	clone: function(){
		return $(this.cloneNode(true));
	},
	replaceWith: function(el){
		var el = $check($(el), $(el), new Element(el));
		this.parentNode.replaceChild(el, this);
		return el;
	},
	appendText: function(text){
		if (this.getTag() == 'style' && window.ActiveXObject) this.styleSheet.cssText = text;
		else this.appendChild(document.createTextNode(text));
		return this;
	},
	hasClassName: function(className){
		return $check(this.className.test("\\b"+className+"\\b"), true);
	},
	addClassName: function(className){
		if (!this.hasClassName(className)) this.className = (this.className+' '+className.trim()).clean();
		return this;
	},
	removeClassName: function(className){
		if (this.hasClassName(className)) this.className = this.className.replace(className.trim(), '').clean();
		return this;
	},
	toggleClassName: function(className){
		if (this.hasClassName(className)) return this.removeClassName(className);
		else return this.addClassName(className);
	},
	setStyle: function(property, value){
		if (property == 'opacity') {
			this.setOpacity(value);
		}
		else {
			if(value != 'NaN' && value != 'undefined' && value != ""){
				try{
					this.style[property.camelCase()] = value;
				}catch(e){	}
			}
		}
		return this;
	},
	setStyles: function(source){
		if ($type(source) == 'object') {
			for (property in source) this.setStyle(property, source[property]);
		} else if ($type(source) == 'string') this.setAttribute('style', source);
		return this;
	},
	setOpacity: function(opacity){
		if (opacity == 0 && this.style.visibility != "hidden") this.style.visibility = "hidden";
		else if (this.style.visibility != "visible") this.style.visibility = "visible";
		if (window.ActiveXObject) this.style.filter = "alpha(opacity=" + opacity*100 + ")";
		this.style.opacity = opacity;
		return this;
	},
	getStyle: function(property, num){
		var proPerty = property.camelCase();
		var style = $check(this.style[proPerty]);
		if (!style) {
			if (document.defaultView) style = document.defaultView.getComputedStyle(this,null).getPropertyValue(property);
			else if (this.currentStyle) style = this.currentStyle[proPerty];
		}
		if (style && ['color', 'backgroundColor', 'borderColor'].test(proPerty) && style.test('rgb')) style = style.rgbToHex();
		if (['auto', 'transparent'].test(style)) style = 0;
		if (num) return parseInt(style);
		else return style;
	},
	removeStyles: function(){
		$A(arguments).each(function(property){
			this.style[property.camelCase()] = '';
		}, this);
		return this;
	},
	addEvent: function(action, fn){
		return EventManager.addEvent(this,action,fn);
	},
	removeEvent: function(action, fn){
		return EventManager.removeEvent(this,action,fn);
	},
	getBrother: function(what){
		var el = this[what+'Sibling'];
		while ($type(el) == 'textnode') el = el[what+'Sibling'];
		return $(el);
	},
	getPrevious: function(){
		return this.getBrother('previous');
	},
	getNext: function(){
		return this.getBrother('next');
	},
	getFirst: function(){
		var el = this.firstChild;
		while ($type(el) == 'textnode') el = el.nextSibling;
		return $(el);
	},
	getLast: function(){
		var el = this.lastChild;
		while ($type(el) == 'textnode')
		el = el.previousSibling;
		return $(el);
	},
	setProperty: function(property, value){
		var el = false;
		switch(property){
			case 'class': this.className = value; break;
			case 'style': this.setStyles(value); break;
			case 'name': if (window.ActiveXObject && this.getTag() == 'input'){
				el = $(document.createElement('<input name="'+value+'" />'));
				$A(this.attributes).each(function(attribute){
					if (attribute.name != 'name') el.setProperty(attribute.name, attribute.value);

				});
				if (this.parentNode) this.replaceWith(el);
			};
			default: this.setAttribute(property, value);
		}
		return el || this;
	},
	setProperties: function(source){
		for (property in source) this.setProperty(property, source[property]);
		return this;
	},
	setHTML: function(html){
		this.innerHTML = html;
		return this;
	},
	getProperty: function(property){
		return this.getAttribute(property);
	},
	getTag: function(){
		return this.tagName.toLowerCase();
	},
	getOffset: function(what){
		what = what.capitalize();
		var el = this;
		var offset = 0;
		do {
			offset += el['offset'+what] || 0;
			el = el.offsetParent;
		} while (el);
		return offset;
	},
	getTop: function(){
		return this.getOffset('top');
	},
	getLeft: function(){
		return this.getOffset('left');
	},
	toLowerString : function(){
		try{
			if(this.getTag() == 'input' || this.getTag() == 'textarea'){
				this.value = this.value.toLowerCase();
			}
		}catch(e){}
	}
});

function $Element(el, method, args){
	if ($type(args) != 'array') args = [args];
	return Element.prototype[method].apply(el, args);
};

new Object.Native(Element);

var mooObjContainer = new Object();

function $(el){
	if ($type(el) == 'string'){
		if(!mooObjContainer[el] || !$cache_mode){
			if(arguments[1] == 'swf'){
				el  = getClient.agent == 'IE' ? window[el] : document[el];
			}else{
				el = document.getElementById(el);
			}
		}else{
			return mooObjContainer[el];
		}
	}
	if ($type(el) == 'element'){
		if (!el.extend){
			Unload.elements.push(el);
			el.extend = Object.extend;
			el.extend(Element.prototype);
		}
		if(arguments[1] != "false"){
			mooObjContainer[el.id] = el;
		}
		return el;
	} else return false;
};

window.addEvent = Element.prototype.addEvent;
window.removeEvent = Element.prototype.removeEvent;

var Unload = {
	elements: [], functions: [], vars: [],
	unload: function(){
		Unload.functions.each(function(fn){
			fn();
		});
		window.removeEvent('unload', window.removeFunction);
		Unload.elements.each(function(el){
			for(p in Element.prototype){
				window[p] = null;
				document[p] = null;
				el[p] = null;
			}
			el.extend = null;
		});
	}
};
window.removeFunction = Unload.unload;
window.addEvent('unload', window.removeFunction);

var Fx = fx = {};

Fx.Base = new Class({

	setOptions: function(options){
		this.options = Object.extend({
			duration: 500,
			onComplete: Class.empty,
			onStart: Class.empty,
			unit: 'px',
			wait: true,
			transition: Fx.sinoidal,
			fps: 30
		}, options || {});
	},
	step: function(){
		var currentTime  = (new Date).getTime();
		if (currentTime >= this.options.duration+this.startTime){
			this.clearTimer();
			this.now = this.to;
			this.options.onComplete.pass(this.el, this).delay(10);
			this.callChain();
		} else {
			this.tPos = (currentTime - this.startTime) / this.options.duration;
			this.setNow();
		}
		this.increase();
	},
	setNow: function(){
		this.now = this.compute(this.from, this.to);
	},
	compute: function(from, to){
		return this.options.transition(this.tPos) * (to-from) + from;
	},
	custom: function(from, to){
		if(!this.options.wait) this.clearTimer();
		if (this.timer) return;
		this.options.onStart.pass(this.el, this).delay(10);
		this.from = from;
		this.to = to;
		this.startTime = (new Date).getTime();
		this.timer = this.step.periodical(Math.round(1000/this.options.fps), this);
		return this;
	},
	set: function(to){
		this.now = to;
		this.increase();
		return this;
	},
	clearTimer: function(){
		this.timer = $clear(this.timer);
		return this;
	},
	setStyle: function(el, property, value){
		if (property == 'opacity'){
			if (value == 1 && navigator.userAgent.test('Firefox')) value = 0.9999;
			el.setOpacity(value);
		} else el.setStyle(property, value+this.options.unit);
	}

});

Fx.Base.implement(new Chain);

Fx.Style = Fx.Base.extend({

	initialize: function(el, property, options){
		this.el = $(el);
		this.setOptions(options);
		this.property = property.camelCase();
	},
	hide: function(){
		return this.set(0);
	},
	goTo: function(val){
		return this.custom(this.now || 0, val);
	},
	increase: function(){
		this.setStyle(this.el, this.property, this.now);
	}
});

Fx.Layout = Fx.Style.extend({
	initialize: function(el, layout, options){
		this.parent(el, layout, options);
		this.layout = layout.capitalize();
		this.el.setStyle('overflow', 'hidden');
	},
	toggle: function(){
		if (this.el['offset'+this.layout] > 0) return this.custom(this.el['offset'+this.layout], 0);
		else return this.custom(0, this.el['scroll'+this.layout]);
	},
	show: function(){
		return this.set(this.el['scroll'+this.layout]);
	}
});

Fx.Scroll = Fx.Base.extend({

	initialize: function(el, options) {
		this.element = $(el);
		this.setOptions(options);
	},
	down: function(){
		return this.custom(this.element.scrollTop, this.element.scrollHeight-this.element.offsetHeight);
	},
	up: function(){
		return this.custom(this.element.scrollTop, 0);
	},
	targetMove: function(target){
		return this.custom(this.element.scrollTop, $(target).getTop());
	},
	increase: function(){
		this.element.scrollTop = this.now;
	}
});

Fx.Height = Fx.Layout.extend({

	initialize: function(el, options){
		this.parent(el, 'height', options);
	}

});

Fx.Width = Fx.Layout.extend({
	initialize: function(el, options){
		this.parent(el, 'width', options);
	}

});

Fx.Opacity = Fx.Style.extend({

	initialize: function(el, options){
		this.parent(el, 'opacity', options);
		this.now = 1;
	},
	toggle: function(){
		if (this.now > 0) return this.custom(1, 0);
		else return this.custom(0, 1);
	},
	show: function(){
		this.set(1);
	}
});

Element.extend({

	effect: function(property, options){
		return new Fx.Style(this, property, options);
	}

});

Fx.sinoidal = function(pos){return ((-Math.cos(pos*Math.PI)/2) + 0.5);};
Fx.linear = function(pos){return pos;};
Fx.cubic = function(pos){return Math.pow(pos, 3);};
Fx.circ = function(pos){return Math.sqrt(pos);};
Fx.expoIn = function(pos){return Math.pow(2, 10 * (pos - 1))};
Fx.expoOut = function(pos){return (-Math.pow(2, -10 * pos) + 1)};
Fx.quadIn = function(pos){return Math.pow(pos, 2)};
Fx.quadOut = function(pos){return -(pos)*(pos-2)};
Fx.circOut = function(pos){return Math.sqrt(1 - Math.pow(pos-1,2))};
Fx.circIn = function(pos){return -(Math.sqrt(1 - Math.pow(pos, 2)) - 1)};
Fx.backIn = function(pos){return (pos)*pos*((2.7)*pos - 1.7)};
Fx.backOut = function(pos){return ((pos-1)*(pos-1)*((2.7)*(pos-1) + 1.7) + 1)};
Fx.sineOut = function(pos){return Math.sin(pos * (Math.PI/2))};
Fx.sineIn = function(pos){return -Math.cos(pos * (Math.PI/2)) + 1};
Fx.sineInOut = function(pos){return -(Math.cos(Math.PI*pos) - 1)/2};
Fx.wobble = function(pos){return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5};
Fx.pulse = function(pos){return (Math.floor(pos*10) % 2 == 0 ? (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10)))};

function $S(){
	var els = [];
	$A(arguments).each(function(sel){
		if ($type(sel) == 'string') els.extend(document.getElementsBySelector(sel));
		else if ($type(sel) == 'element') els.push($(sel));
	});
	return $$(els);
};

function $E(selector, filter){
	return ($(filter) || document).getElement(selector);
};

function $$(elements){
	return Object.extend(elements, new Elements);
};

Element.extend({
	getElements: function(selector){
		var filters = [];
		selector.clean().split(' ').each(function(sel, i){
			var bits = [];
			var param = [];
			var attr = [];
			if (bits = sel.test('^([\\w]*)')) param['tag'] = bits[1] || '*';
			if (bits = sel.test('([.#]{1})([\\w-]*)$')){
				if (bits[1] == '.') param['class'] = bits[2];
				else param['id'] = bits[2];
			}
			if (bits = sel.test('\\[["\'\\s]{0,1}([\\w-]*)["\'\\s]{0,1}([\\W]{0,1}=){0,2}["\'\\s]{0,1}([\\w-]*)["\'\\s]{0,1}\\]$')){
				attr['name'] = bits[1];
				attr['operator'] = bits[2];
				attr['value'] = bits[3];
			}
			if (i == 0){
				if (param['id']){
					var el = this.getElementById(param['id']);
					if (el && (param['tag'] == '*' || $(el).getTag() == param['tag'])) filters = [el];
					else return false;
				} else {
					filters = $A(this.getElementsByTagName(param['tag']));
				}
			} else {
				filters = $$(filters).filterByTagName(param['tag']);
				if (param['id']) filters = $$(filters).filterById(param['id']);
			}
			if (param['class']) filters = $$(filters).filterByClassName(param['class']);
			if (attr['name']) filters = $$(filters).filterByAttribute(attr['name'], attr['value'], attr['operator']);

		}, this);
		filters.each(function(el){
			$(el);
		});
		return $$(filters);
	},
	getElement: function(selector){
		return this.getElementsBySelector(selector)[0];
	},
	getElementsBySelector: function(selector){
		var els = [];
		selector.split(',').each(function(sel){
			els.extend(this.getElements(sel));
		}, this);
		return $$(els);
	}
});

document.extend = Object.extend;

document.extend({
	getElementsByClassName: function(className){
		return document.getElements('.'+className);
	},
	getElement: Element.prototype.getElement,
	getElements: Element.prototype.getElements,
	getElementsBySelector: Element.prototype.getElementsBySelector
});

var Elements = new Class({
	action: function(actions){
		this.each(function(el){
			el = $(el);
			if (actions.initialize) actions.initialize.apply(el);
			for(action in actions){
				var evt = false;
				if (action.test('^on[\\w]{1,}')) el[action] = actions[action];
				else if (evt = action.test('([\\w-]{1,})event$')) el.addEvent(evt[1], actions[action]);
			}
		});
	},
	filterById: function(id){
		var found = [];
		this.each(function(el){
			if (el.id == id) found.push(el);
		});
		return found;
	},
	filterByClassName: function(className){
		var found = [];
		this.each(function(el){
			if ($Element(el, 'hasClassName', className)) found.push(el);
		});
		return found;
	},
	filterByTagName: function(tagName){
		var found = [];
		this.each(function(el){
			found.extend($A(el.getElementsByTagName(tagName)));
		});
		return found;
	},
	filterByAttribute: function(name, value, operator){
		var found = [];
		this.each(function(el){
			var att = el.getAttribute(name);
			if(!att) return;
			if (!operator) return found.push(el);
			switch(operator){
				case '*=': if (att.test(value)) found.push(el); break;
				case '=': if (att == value) found.push(el); break;
				case '^=': if (att.test('^'+value)) found.push(el); break;
				case '$=': if (att.test(value+'$')) found.push(el);
			}
		});
		return found;
	}
});

new Object.Native(Elements);


var Ajax = ajax = new Class({

	setOptions: function(options){
		this.options = {
			method: 'post',
			postBody: null,
			async: true,
			onComplete: Class.empty,
			onStateChange: Class.empty,
			onFailure: Class.empty,
			update: null,
			evalScripts: false,
			addReq: []
		};
		Object.extend(this.options, options || {});
	},
	initialize: function(url, options){
		this.setOptions(options);
		this.url = url;
		this.transport = this.getTransport();
	},
	request: function(){
		this.transport.open(this.options.method, this.url, this.options.async);
		this.transport.onreadystatechange = this.onStateChange.bind(this);
		if (this.options.method == 'post'){
			this.transport.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
			if(this.options.addReq.length > 1){
				for(var i=0;i< this.options.addReq.length;i++){
					this.transport.setRequestHeader(this.options.addReq[i]['key'],this.options.addReq[i]['value']);
				}
			}
			if (this.transport.overrideMimeType) this.transport.setRequestHeader('Connection', 'close');
		}
		switch($type(this.options.postBody)){
			case 'element': this.options.postBody = $(this.options.postBody).toQueryString(); break;
			case 'object': this.options.postBody = Object.toQueryString(this.options.postBody);
		}
		debug.log(this.options.postBody);
		this.transport.send(this.options.postBody);
		return this;
	},
	onStateChange: function(){
		this.options.onStateChange.delay(10, this);
		if (this.transport.readyState != 4) return;
		if (!this.transport.status || (this.transport.status >= 200 && this.transport.status < 300)){
			if (this.options.update) $(this.options.update).setHTML(this.transport.responseText);
			this.options.onComplete.pass([this.transport.responseText, this.transport.responseXML], this).delay(20);
			if (this.options.evalScripts) this.evalScripts.delay(30, this);
			//cacheÇØÁ¦
			mooObjContainer = "";
		} else this.options.onFailure.delay(20, this);
		this.transport.onreadystatechange = Class.empty;
		this.callChain();
	},
	evalScripts: function(){
		if(scripts = this.transport.responseText.match(/<script[^>]*?>[\S\s]*?<\/script>/g)){
			scripts.each(function(script){
				eval(script.replace(/^<script[^>]*?>/, '').replace(/<\/script>$/, ''));
			});
		}
	},
	getTransport: function(){
		if (window.XMLHttpRequest) return new XMLHttpRequest();
		else if (window.ActiveXObject) return new ActiveXObject('Microsoft.XMLHTTP');
	}
});

Ajax.implement(new Chain);

Object.toQueryString = function(source){
	var queryString = [];
	for (property in source) queryString.push(encodeURIComponent(property)+'='+encodeURIComponent(source[property]));
	return queryString.join('&');
};

Element.extend({

	send: function(options){
		options = Object.extend(options, {postBody: this.toQueryString(), method: 'post'});
		return new Ajax(this.getProperty('action'), options).request();
	},
	toQueryString: function(){
		var queryString = [];
		$A(this.getElementsByTagName('*')).each(function(el){
			$(el);
			var name = $check(el.name);
			if (!name) return;
			var value = false;
			switch(el.getTag()){
				case 'select': value = el.getElementsByTagName('option')[el.selectedIndex].value; break;
				case 'input': if ( (el.checked && ['checkbox', 'radio'].test(el.type)) || (['hidden', 'text', 'password'].test(el.type)) )
					value = el.value; break;
				case 'textarea': value = el.value;
			}
			if (value) queryString.push(encodeURIComponent(name)+'='+encodeURIComponent(value));
		});
		return queryString.join('&');
	}
});

var Drag = {};

Drag.Base = new Class({
	setOptions: function(options){
		this.options = Object.extend({
			handle: false,
			unit: 'px',
			onStart: Class.empty,
			onComplete: Class.empty,
			onDrag: Class.empty
		}, options || {});
	},
	initialize: function(el, xModifier, yModifier, options){
		this.setOptions(options);
		this.el = $(el);
		this.handle = $(this.options.handle) || el;
		if (xModifier) this.xp = xModifier.camelCase();
		if (yModifier) this.yp = yModifier.camelCase();
		this.handle.onmousedown = this.start.bind(this);
	},
	start: function(evt){
		evt = evt || window.event;
		this.startX = evt.clientX;
		this.startY = evt.clientY;
		this.options.onStart.pass(this.el, this).delay(10);
		document.onmousemove = this.drag.bind(this);
		document.onmouseup = this.end.bind(this);
		return false;
	},
	addStyles: function(x, y){
		if (this.xp) this.el.setStyle(this.xp, (this.el.getStyle(this.xp, true)+x)+this.options.unit);
		if (this.yp) this.el.setStyle(this.yp, (this.el.getStyle(this.yp, true)+y)+this.options.unit);
	},
	drag: function(evt){
		evt = evt || window.event;
		this.clientX = evt.clientX;
		this.clientY = evt.clientY;
		this.options.onDrag.pass(this.el, this).delay(10);
		this.addStyles((this.clientX-this.lastMouseX), (this.clientY-this.lastMouseY));
		this.set(evt);
		return false;
	},
	pause: function(){
		this.handle.onmousedown = null;
	},
	resume: function(){
		this.handle.onmousedown = this.start.bind(this);
	},
	set: function(evt){
		this.lastMouseX = evt.clientX;
		this.lastMouseY = evt.clientY;
		return false;
	},
	end: function(){
		document.onmousemove = null;
		document.onmouseup = null;
		this.options.onComplete.pass(this.el, this).delay(10);
	}
});

Drag.Move = Drag.Base.extend({

	extendOptions: function(options){
		this.options = Object.extend(this.options || {}, Object.extend({
			onSnap: Class.empty,
			droppables: [],
			snapDistance: 8,
			snap: true,
			xModifier: 'left',
			yModifier: 'top'
		}, options || {}));
	},
	initialize: function(el, options){
		this.extendOptions(options);
		this.parent(el, this.options.xModifier, this.options.yModifier, this.options);
	},
	start: function(evt){
		this.parent(evt);
		this.clearSelection();
		if (this.options.snap){
			document.onmousemove = this.checkAndDrag.bind(this);
		} else {
			this.set(evt);
			document.onmousemove = this.drag.bind(this);
		}
		return false;
	},
	drag: function(evt){
		this.parent(evt);
		this.options.droppables.each(function(drop){
			if (this.checkAgainst(drop)){
				if (drop.onOver && !drop.dropping) drop.onOver.pass([this.el, this], drop).delay(10);
				drop.dropping = true;
			} else {
				if (drop.onLeave && drop.dropping) drop.onLeave.pass([this.el, this], drop).delay(10);
				drop.dropping = false;
			}
		}, this);
		return false;
	},
	clearSelection : function(){
		try{
			if(window["getSelection"]){
				window.getSelection().removeAllRanges();
			}else if((document.selection)&&(document.selection.clear)){
				document.selection.clear();
			}
			return true;
		}catch(e){
		}
	},
	checkAndDrag: function(evt){
		evt = evt || window.event;
		var distance = Math.round(Math.sqrt(Math.pow(evt.clientX - this.startX, 2)+Math.pow(evt.clientY - this.startY, 2)));
		if (distance > this.options.snapDistance){
			this.set(evt);
			this.options.onSnap.pass(this.el, this).delay(10);
			document.onmousemove = this.drag.bind(this);
			this.addStyles(-(this.startX-evt.clientX), -(this.startY-evt.clientY));
		}
		return false;
	},
	checkAgainst: function(drop){
		x = this.clientX+Window.getScrollLeft();
		y = this.clientY+Window.getScrollTop();
		drop = $(drop);
		var h = drop.offsetHeight;
		var w = drop.offsetWidth;
		var t = drop.getTop();
		var l = drop.getLeft();
		//Hit Checker
		return $check((x > l && x < l+w && y < t+h && y > t));
	},
	end: function(){
		this.parent();
		this.options.droppables.each(function(drop){
			if (drop.onDrop && this.checkAgainst(drop)) drop.onDrop.pass([this.el, this], drop).delay(10);
		}, this);
	}
});

Element.extend({
	makeDraggable: function(options){
		return new Drag.Move(this, options);
	},
	makeResizable: function(options){
		return new Drag.Base(this, 'width', 'height', options);
	}
});


var Window = {
	extend: Object.extend,
	getWidth: function(){
		return window.innerWidth || document.documentElement.clientWidth || 0;
	},
	getHeight: function(){
		return window.innerHeight || document.documentElement.clientHeight || 0;
	},
	getScrollHeight: function(){
		return document.documentElement.scrollHeight;
	},
	getScrollWidth: function(){
		return document.documentElement.scrollWidth;
	},
	getScrollTop: function(){
		return document.documentElement.scrollTop || window.pageYOffset || 0;
	},
	getScrollLeft: function(){
		return document.documentElement.scrollLeft || window.pageXOffset || 0;
	},
	onLoad: function(fn){
		if (!document.body) return Window.onLoad.pass(fn).delay(50);
		else return fn();
	},
	onDomReady: function(init){
        if(!this._readyCallbacks) {
            var domReady = function(){
                if (arguments.callee.done) return;
                arguments.callee.done = true;
                this._timer = $clear(this._timer);
                this._readyCallbacks.each(function(f) { f(); });
                this._readyCallbacks = null;
            }.bind(this);
            var state = document.readyState;
            if (state && document.childNodes && !document.all && !navigator.taintEnabled){ //khtml
                this._timer = function(){
                    if (document.readyState.test(/loaded|complete/)) domReady();
                }.periodical(50);
            } else if (state && window.ActiveXObject){ //ie
                document.write("<script id=_ie_ready_ defer src=javascript:void(0)><\/script>");
                $('_ie_ready_').onreadystatechange = function(){
                    if (this.readyState == 'complete') domReady();
                };
            } else { //others
                window.addEvent("load", domReady);
                 EventManager.addEvent(document,"DOMContentLoaded", domReady);
            }
            this._readyCallbacks = [];
        }
        this._readyCallbacks.push(init);
    }
};


var Cookie = {
	/**
	 * setCookie
	 * @param {Object} key
	 * @param {Object} value
	 * @param {Object} duration À¯Áö±â°£
	 * @param {Object} path °æ·Î
	 * @param {Object} domain ÄíÅ°µµ¸ÞÀÎ
	 * @param {Object} secure https¿©ºÎ
	 */
	set: function(key, value, duration,path,domain,secure){
		var date = new Date();
		path = path || "/";
		domain = domain || "gseshop.co.kr";
		secure = secure || false;
		date.setTime(date.getTime()+((duration || 365)*86400000));
		var sb = new StringBuffer();
		sb.append(key + "=" + encodeURIComponent(value))
			.append(";expires=" + date.toGMTString())
			.append(";path=" + path)
			.append(";domain=" + domain)
			.append((secure) ? "; secure" : "");

		document.cookie = sb.toString();
	},
	get: function(key){
		var myValue, myVal;
		document.cookie.split(';').each(function(cookie){
			myVal = cookie.trim().split("=");
			if(myVal[0] == key){
				try{
					myValue = decodeURIComponent(myVal[1]);
				}catch(e){
					myValue = unescape(myVal[1]);
				}
			}
		});
		return myValue;
	},

	remove: function(key){
		this.set(key, '', -1);
	}
};

var Json = {
	toString: function(el){
		var string = [];
		var isArray = function(array){
			var string = [];
			array.each(function(ar){
				string.push(Json.toString(ar));
			});
			return string.join(',');
		};
		var isObject = function(object){
			var string = [];
			for (property in object) string.push('"'+property+'":'+Json.toString(object[property]));
			return string.join(',');
		};
		switch($type(el)){
			case 'string': string.push('"'+el+'"'); break;
			case 'number' : string.push(el); break;
			case 'function': string.push(el); break;
			case 'object': string.push('{'+isObject(el)+'}'); break;
			case 'array': string.push('['+isArray(el)+']');break;
			default : string.push('""'); break;
		}
		return string.join(',');
	},
	evaluate: function(str){
		return eval('(' + str + ')');
	}
};

Fx.Styles = Fx.Base.extend({
	initialize: function(el, options){
		this.el = $(el);
		this.setOptions(options);
		this.now = {};
	},
	setNow: function(){
		for (p in this.from) this.now[p] = this.compute(this.from[p], this.to[p]);
	},
	custom: function(objFromTo){
		var from = {};
		var to = {};
		for (p in objFromTo){
			from[p] = objFromTo[p][0];
			to[p] = objFromTo[p][1];
		}
		return this.parent(from, to);
	},
	resizeTo: function(hto, wto){
		return this.custom({'height': [this.el.offsetHeight, hto], 'width': [this.el.offsetWidth, wto]});
	},
	resizeBy: function(hby, wby){
		return this.custom({'height': [this.el.offsetHeight, this.el.offsetHeight+hby], 'width': [this.el.offsetWidth, this.el.offsetWidth+wby]});
	},
	increase: function(){
		for (p in this.now) this.setStyle(this.el, p, this.now[p]);
	}
});

Fx.Color = Fx.Base.extend({
	initialize: function(el, property, options){
		this.el = $(el);
		this.setOptions(options);
		this.property = property.camelCase();
		this.now = [];
	},
	custom: function(from, to){
		return this.parent(from.hexToRgb(true), to.hexToRgb(true));
	},
	setNow: function(){
		[0,1,2].each(function(i){
			this.now[i] = Math.round(this.compute(this.from[i], this.to[i]));
		}, this);
	},
	increase: function(){
		this.el.setStyle(this.property, "rgb("+this.now[0]+","+this.now[1]+","+this.now[2]+")");
	},
	fromColor: function(color){
		return this.custom(color, this.el.getStyle(this.property));
	},
	toColor: function(color){
		return this.custom(this.el.getStyle(this.property), color);
	}
});

Element.extend({
	effects: function(options){
		return new Fx.Styles(this, options);
	}
});

var StringBuffer = new Class({
	buffer : [],
	initialize : function(){
		this.buffer = [];
	},
	append : function(str){
		this.buffer.push(str);
		return this;
	},
	toString : function(){
		return this.buffer.join("");
	}
});


var debug = {
	logTrace : "",
	log : function(msg){
		this.logTrace += '>>> ' + msg + '\n';
		$('trace').value +=  '>>> ' + msg + '\n';
	},
	showlog : function(){
		if($('trace')){
			$('trace').value =  this.logTrace;
			$('traceDiv').style.display = $('traceDiv').style.display=='block'?'none':'block';
		}else{
			var traceDiv = new Element('div');
			var traceInnerDiv = new Element('div').setHTML('<b>JavaScript LOG</b>');
			traceInnerDiv.setStyles({height:'20px',color:'#FFFFFF'});
			traceDiv.setStyles({width:'700px',height:'300px',top:'0px','left':'0px',position:'absolute',zIndex:'1000000',border:'2px',backgroundColor:'#000000'});
			var traceTxt = new Element('textarea');
			traceTxt.id = 'trace';
			traceTxt.setStyles({width:'700px',height:'300px'});
			traceDiv.adopt(traceInnerDiv);
			traceDiv.adopt(traceTxt);
			traceDiv.id="traceDiv";
			document.body.appendChild(traceDiv);
			$('trace').value =  "" + this.logTrace;
			this.commonDrag(traceInnerDiv);
		}
	},
	trace : function(msg){
		this.log('trace : ' + msg);
		this.showlog();
	},
	inspect:function(obj){
		for(var i in obj){
			this.log(i + ':' + obj[i]);
		}
	},
	source : function(){
		try{
			this.logTrace  = getClient.agent == 'FF' ? (new XMLSerializer).serializeToString(document.getElementsByTagName("html")[0]) :
				document.getElementsByTagName("html")[0].outerHTML;
		}catch(e){
		}
		this.showlog();
	},
	commonDrag : function(el){
	 var dragContainerOptions = {
		handle: el,
		onStart: function(){}.bind(this),
		onDrag : function(){}.bind(this),
		onComplete: function(){}.bind(this)
	 };
	 el.setStyle('cursor','move');
	 el.parentNode.makeDraggable(dragContainerOptions);
	}
}