//init page
$(function(){
	initTabs();
	initTextInput();
	initNavIndexes();
	//initClearInputs();
	initCustomForms();
	VSA_initScrollbars();
});

//init text input
function initTextInput(){
	var inputs = $('input:text, input:password');
	
	inputs.focus(function(){
		$(this).css({color: '#000000'});		
	});
	inputs.blur(function(){
		if(this.value == this.defaultValue || this.value == ''){
			$(this).css({color: ''});		
		}
	});
}

//init nav indexes
function initNavIndexes(){
	var nav = document.getElementById("nav");
	if(nav){
		var lis = nav.getElementsByTagName("li");
		for (var i=0; i<lis.length; i++){
			lis[i].style.zIndex = lis.length-i;
			//lis[i].style.zIndex = lis.length-i;
		}
	}
}

//init clear inputs
function initClearInputs(){
	clearFormFields({
		clearInputs: true,
		clearTextareas: true,
		passwordFieldText: true,
		addClassFocus: "focus",
		filterClass: "default"
	});
}

//init tabs
function initTabs(){
	var sets = document.getElementsByTagName("ul");
	for (var i = 0; i < sets.length; i++){
		if (sets[i].className.indexOf("tabset") != -1){
			var tabs = [];
			var links = sets[i].getElementsByTagName("a");
			for (var j = 0; j < links.length; j++){
				if (links[j].className.indexOf("tab") != -1){
					tabs.push(links[j]);
					links[j].tabs = tabs;
					var c = document.getElementById(links[j].href.substr(links[j].href.indexOf("#") + 1));

					if (c) if (links[j].className.indexOf("active") != -1) c.style.display = "block";
					else c.style.display = "none";

					links[j].onclick = function (){
						var c = document.getElementById(this.href.substr(this.href.indexOf("#") + 1));
						if (c){
							for (var i = 0; i < this.tabs.length; i++){
								var tab = document.getElementById(this.tabs[i].href.substr(this.tabs[i].href.indexOf("#") + 1));
								if (tab){
									tab.style.display = "none";
								}
								this.tabs[i].className = this.tabs[i].className.replace("active", "");
							}
							this.className += " active";
							c.style.display = "block";
							return false;
						}
					}
				}
			}
		}
	}
}

//clear form fields
function clearFormFields(o){
	if (o.clearInputs == null) o.clearInputs = true;
	if (o.clearTextareas == null) o.clearTextareas = true;
	if (o.passwordFieldText == null) o.passwordFieldText = false;
	if (o.addClassFocus == null) o.addClassFocus = false;
	if (!o.filterClass) o.filterClass = "default";
	if(o.clearInputs) {
		var inputs = document.getElementsByTagName("input");
		for (var i = 0; i < inputs.length; i++ ) {
			if((inputs[i].type == "text" || inputs[i].type == "password") && inputs[i].className.indexOf(o.filterClass) == -1) {
				inputs[i].valueHtml = inputs[i].value;
				inputs[i].onfocus = function ()	{
					if(this.valueHtml == this.value) this.value = "";
					if(this.fake) {
						inputsSwap(this, this.previousSibling);
						this.previousSibling.focus();
					}
					if(o.addClassFocus && !this.fake) {
						this.className += " " + o.addClassFocus;
						this.parentNode.className += " parent-" + o.addClassFocus;
					}
				}
				inputs[i].onblur = function () {
					if(this.value == "") {
						this.value = this.valueHtml;
						if(o.passwordFieldText && this.type == "password") inputsSwap(this, this.nextSibling);
					}
					if(o.addClassFocus) {
						this.className = this.className.replace(o.addClassFocus, "");
						this.parentNode.className = this.parentNode.className.replace("parent-"+o.addClassFocus, "");
					}
				}
				if(o.passwordFieldText && inputs[i].type == "password") {
					var fakeInput = document.createElement("input");
					fakeInput.type = "text";
					fakeInput.value = inputs[i].value;
					fakeInput.className = inputs[i].className;
					fakeInput.fake = true;
					inputs[i].parentNode.insertBefore(fakeInput, inputs[i].nextSibling);
					inputsSwap(inputs[i], null);
				}
			}
		}
	}
	if(o.clearTextareas) {
		var textareas = document.getElementsByTagName("textarea");
		for(var i=0; i<textareas.length; i++) {
			if(textareas[i].className.indexOf(o.filterClass) == -1) {
				textareas[i].valueHtml = textareas[i].value;
				textareas[i].onfocus = function() {
					if(this.value == this.valueHtml) this.value = "";
					if(o.addClassFocus) {
						this.className += " " + o.addClassFocus;
						this.parentNode.className += " parent-" + o.addClassFocus;
					}
				}
				textareas[i].onblur = function() {
					if(this.value == "") this.value = this.valueHtml;
					if(o.addClassFocus) {
						this.className = this.className.replace(o.addClassFocus, "");
						this.parentNode.className = this.parentNode.className.replace("parent-"+o.addClassFocus, "");
					}
				}
			}
		}
	}
	function inputsSwap(el, el2) {
		if(el) el.style.display = "none";
		if(el2) el2.style.display = "inline";
	}
}

//init custom scroll
var VSA_scrollAreas = new Array();
var VSA_default_imagesPath = "Img";
var VSA_default_btnUpImage = "button-up.gif";
var VSA_default_btnDownImage = "button-down.gif";
var VSA_default_scrollStep = 5;
var VSA_default_wheelSensitivity = 10;
var VSA_default_scrollbarPosition = 'right';//'left','right','inline';
var VSA_default_scrollButtonHeight = 0;
var VSA_default_scrollbarWidth = 10;
var VSA_resizeTimer = 2000;
var VSA_touchFlag = isTouchDevice(); // true/false - move scroll with scrollable body

function VSA_initScrollbars() {
	if(!document.body.children) return;
	var scrollElements = VSA_getElements("vscrollable", "DIV", document, "class");
	for (var i=0; i<scrollElements.length; i++){
		VSA_scrollAreas[i] = new VScrollArea(i, scrollElements[i]);
	}
}
window.VSA_initScrollbars = VSA_initScrollbars;
function isTouchDevice() {
	try {
		document.createEvent("TouchEvent");
		return true;
	} catch (e) {
		return false;
	}
}

function touchHandler(event) {
	var touches = event.changedTouches, first = touches[0], type = "";
	switch(event.type) {
		case "touchstart": type = "mousedown"; break;
		case "touchmove":  type = "mousemove"; break;
		case "touchend":   type = "mouseup"; break;
		default: return;
	}
	var simulatedEvent = document.createEvent("MouseEvent");
	simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0/*left*/, null);
	first.target.dispatchEvent(simulatedEvent);
	event.preventDefault();
}

function VScrollArea(index, elem){ //constructor

	this.index = index;
	this.element = elem;

	var attr = this.element.getAttribute("imagesPath");
	this.imagesPath = attr ? attr : VSA_default_imagesPath;

	attr = this.element.getAttribute("btnUpImage");
	this.btnUpImage = attr ? attr : VSA_default_btnUpImage;

	attr = this.element.getAttribute("btnDownImage");
	this.btnDownImage = attr ? attr : VSA_default_btnDownImage;

	attr = Number(this.element.getAttribute("scrollStep"));
	this.scrollStep = attr ? attr : VSA_default_scrollStep;

	attr = Number(this.element.getAttribute("wheelSensitivity"));
	this.wheelSensitivity = attr ? attr : VSA_default_wheelSensitivity;

	attr = this.element.getAttribute("scrollbarPosition");
	this.scrollbarPosition = attr ? attr : VSA_default_scrollbarPosition;
	
	attr = this.element.getAttribute("scrollButtonHeight");
	this.scrollButtonHeight = attr ? attr : VSA_default_scrollButtonHeight;

	attr = this.element.getAttribute("scrollbarWidth");
	this.scrollbarWidth = attr ? attr : VSA_default_scrollbarWidth;

	this.scrolling = false;

	this.iOffsetY = 0;
	this.scrollHeight = 0;
	this.scrollContent = null;
	this.scrollbar = null;
	this.scrollup = null;
	this.scrolldown = null;
	this.scrollslider = null;
	this.scroll = null;
	this.enableScrollbar = false;
	this.scrollFactor = 1;
	this.scrollingLimit = 0;
	this.topPosition = 0;

	//functions declaration
	this.init = VSA_init;
	this.scrollUp = VSA_scrollUp;
	this.scrollDown = VSA_scrollDown;
	this.createScrollBar = VSA_createScrollBar;
	this.scrollIt = VSA_scrollIt;

	this.init();
}

function VSA_init() {
	this.scrollContent = document.createElement("DIV");
	this.scrollContent.style.position = "absolute";
	this.scrollContent.style.overflow = "hidden";
	this.scrollContent.style.width = this.element.offsetWidth + "px";
	this.scrollContent.style.height = this.element.offsetHeight + "px";

	while(this.element.childNodes.length) this.scrollContent.appendChild(this.element.childNodes[0]);

	this.element.style.overflow = "hidden";
	this.element.style.display = "block";
	this.element.style.visibility = "visible";
	this.element.style.position = "relative";
	this.element.appendChild(this.scrollContent);

	this.scrollContent.className = 'scroll-content';

	this.element.index = this.index;
	this.element.over = false;
	
	var _this = this;

	if(document.all && !window.opera) {
		this.element.onmouseenter = function(){_this.element.over = true;};
		this.element.onmouseleave = function(){_this.element.over = false;}
	} else {
		this.element.onmouseover = function(){_this.element.over = true;};
		this.element.onmouseout = function(){_this.element.over = false;}
	}

	if (document.all){
		this.element.onscroll = VSA_handleOnScroll;
		this.element.onresize = VSA_handleResize;
	}else{
		window.onresize = VSA_handleResize;
	}
	
	this.createScrollBar();
	
	if (window.addEventListener) {
		/* DOMMouseScroll is for mozilla. */
		this.element.addEventListener('DOMMouseScroll', VSA_handleMouseWheel, false);
	}
	/* IE/Opera. */
	this.element.onmousewheel = document.onmousewheel = VSA_handleMouseWheel;

	// move content by touch
	if(VSA_touchFlag) {
		_this.scrollContent.onmousedown = function(e) {
			var startY = e.pageY-getRealTop(_this.scrollContent);
			var origTop = _this.scrollContent.scrollTop;
			_this.scrollContent.onmousemove = function(e) {
				var moveY = e.pageY-getRealTop(_this.scrollContent);
				var iNewY = origTop-(moveY-startY);
				if(iNewY < 0) iNewY = 0;
				if(iNewY > _this.scrollContent.scrollHeight) iNewY = _this.scrollContent.scrollHeight;
				_this.scrollContent.scrollTop = iNewY;
				_this.scrollslider.style.top =  1 / _this.scrollFactor * Math.abs(_this.scrollContent.scrollTop) + _this.scrollButtonHeight + "px";
			}
		}
		_this.scrollContent.onmouseup = function(e) {
			_this.scrollContent.onmousemove = null;
		}
		this.scrollContent.addEventListener("touchstart", touchHandler, true);
		this.scrollContent.addEventListener("touchmove", touchHandler, true);
		this.scrollContent.addEventListener("touchend", touchHandler, true);
	}
}

function VSA_createScrollBar(){
	if (this.scrollbar != null){
		this.element.removeChild(this.scrollbar);
		this.scrollbar = null;
	}
	
	if (this.scrollContent.scrollHeight <= this.scrollContent.offsetHeight)
		this.enableScrollbar = false;
	else if (this.element.offsetHeight > 2*this.scrollButtonHeight)
		this.enableScrollbar = true;
	else
		this.enableScrollbar = false;

	if (this.scrollContent.scrollHeight - Math.abs(this.scrollContent.scrollTop) < this.element.offsetHeight)
		this.scrollContent.style.top = 0;

	if (this.enableScrollbar){
		this.scrollbar = document.createElement("DIV");
		this.element.appendChild(this.scrollbar);
		this.scrollbar.style.position = "absolute";
		this.scrollbar.style.top = "0px";
		this.scrollbar.style.height = this.element.offsetHeight+"px";
		this.scrollbar.style.width = this.scrollbarWidth + "px";

		this.scrollbar.className = 'vscroll-bar';

		if(this.scrollbarWidth != this.scrollbar.offsetWidth){
			this.scrollbarWidth = this.scrollbar.offsetHeight;
		}
		
		this.scrollbarWidth = this.scrollbar.offsetWidth;

		if(this.scrollbarPosition == 'left'){
			this.scrollContent.style.left = this.scrollbarWidth + 5 + "px";
			this.scrollContent.style.width = this.element.offsetWidth - this.scrollbarWidth - 5 + "px";
		}else if(this.scrollbarPosition == 'right'){
			this.scrollbar.style.left = this.element.offsetWidth - this.scrollbarWidth  + "px";
			this.scrollContent.style.width = this.element.offsetWidth - this.scrollbarWidth - 5 + "px";
		}

		//create scroll up button
		this.scrollup = document.createElement("DIV");
		this.scrollup.index = this.index;
		this.scrollup.onmousedown = VSA_handleBtnUpMouseDown;
		this.scrollup.onmouseup = VSA_handleBtnUpMouseUp;
		this.scrollup.onmouseout = VSA_handleBtnUpMouseOut;
		
		if(VSA_touchFlag) {
			this.scrollup.addEventListener("touchstart", touchHandler, true);
			this.scrollup.addEventListener("touchend", touchHandler, true);
		}
		
		this.scrollup.style.position = "absolute";
		this.scrollup.style.top = "0px";
		this.scrollup.style.left = "0px";
		this.scrollup.style.height = this.scrollButtonHeight + "px";
		this.scrollup.style.width = this.scrollbarWidth + "px";
		
		this.scrollup.innerHTML = '<img src="' + this.imagesPath + '/' + this.btnUpImage + '" border="0"/>';
		this.scrollbar.appendChild(this.scrollup);

		this.scrollup.className = 'vscroll-up';

		if(this.scrollButtonHeight != this.scrollup.offsetHeight){
			this.scrollButtonHeight = this.scrollup.offsetHeight;
		}
		
		//create scroll down button
		this.scrolldown = document.createElement("DIV");
		this.scrolldown.index = this.index;
		this.scrolldown.onmousedown = VSA_handleBtnDownMouseDown;
		this.scrolldown.onmouseup = VSA_handleBtnDownMouseUp;
		this.scrolldown.onmouseout = VSA_handleBtnDownMouseOut;
		
		if(VSA_touchFlag) {
			this.scrolldown.addEventListener("touchstart", touchHandler, true);
			this.scrolldown.addEventListener("touchend", touchHandler, true);
		}
		
		this.scrolldown.style.position = "absolute";
		this.scrolldown.style.left = "0px";
		this.scrolldown.style.top =  this.scrollbar.offsetHeight - this.scrollButtonHeight + "px";
		this.scrolldown.style.width = this.scrollbarWidth + "px";
		this.scrolldown.innerHTML = '<img src="' + this.imagesPath + '/' + this.btnDownImage + '" border="0"/>';
		this.scrollbar.appendChild(this.scrolldown);

		this.scrolldown.className = 'vscroll-down';

		//create scroll
		this.scroll = document.createElement("DIV");
		this.scroll.index = this.index;
		this.scroll.style.position = "absolute";
		this.scroll.style.zIndex = 0;
		this.scroll.style.textAlign = "center";
		this.scroll.style.top = this.scrollButtonHeight + "px";
		this.scroll.style.left = "0px";
		this.scroll.style.width = this.scrollbarWidth + "px";
		
		var h = this.scrollbar.offsetHeight - 2*this.scrollButtonHeight;
		this.scroll.style.height = ((h > 0) ? h : 0) + "px";
		
		this.scroll.innerHTML = '';
		this.scroll.onclick = VSA_handleScrollbarClick;
		this.scrollbar.appendChild(this.scroll);
		this.scroll.style.overflow = "hidden";

		this.scroll.className = "vscroll-line";

		//create slider
		this.scrollslider = document.createElement("DIV");
		this.scrollslider.index = this.index;
		this.scrollslider.style.position = "absolute";
		this.scrollslider.style.zIndex = 1000;
		this.scrollslider.style.textAlign = "center";
		this.scrollslider.innerHTML = '<div id="vscrollslider' + this.index + '" style="padding:0;margin:0;"><div class="scroll-bar-top"></div><div class="scroll-bar-bottom"></div></div>';
		this.scrollbar.appendChild(this.scrollslider);
		
		this.subscrollslider = document.getElementById("vscrollslider"+this.index);
		this.subscrollslider.style.height = Math.round((this.scrollContent.offsetHeight/this.scrollContent.scrollHeight)*(this.scrollbar.offsetHeight - 2*this.scrollButtonHeight)) + "px";
		
		this.scrollslider.className = "vscroll-slider";
		
		this.scrollHeight = this.scrollbar.offsetHeight - 2*this.scrollButtonHeight - this.scrollslider.offsetHeight;
		this.scrollFactor = (this.scrollContent.scrollHeight - this.scrollContent.offsetHeight)/this.scrollHeight;
		this.topPosition = getRealTop(this.scrollbar) + this.scrollButtonHeight;
		/* this.scrollbarHeight = this.scrollbar.offsetHeight - 2*this.scrollButtonHeight - this.scrollslider.offsetHeight; */

		this.scrollslider.style.top = /* 1 / this.scrollFactor * Math.abs(this.scrollContent.offsetTop) +*/ this.scrollButtonHeight + "px";
		this.scrollslider.style.left = "0px";
		this.scrollslider.style.width = "100%";
		this.scrollslider.onmousedown = VSA_handleSliderMouseDown;
		if(VSA_touchFlag) {
			this.scrollslider.addEventListener("touchstart", touchHandler, true);
		}
		if (document.all)
			this.scrollslider.onmouseup = VSA_handleSliderMouseUp;
	}else
		this.scrollContent.style.width = this.element.offsetWidth + "px";
}

function VSA_handleBtnUpMouseDown(){
	var sa = VSA_scrollAreas[this.index];
	sa.scrolling = true;
	sa.scrollUp();
}

function VSA_handleBtnUpMouseUp(){
	VSA_scrollAreas[this.index].scrolling = false;
}

function VSA_handleBtnUpMouseOut(){
	VSA_scrollAreas[this.index].scrolling = false;
}

function VSA_handleBtnDownMouseDown(){
	var sa = VSA_scrollAreas[this.index];
	sa.scrolling = true;
	sa.scrollDown();
}

function VSA_handleBtnDownMouseUp(){
	VSA_scrollAreas[this.index].scrolling = false;
}

function VSA_handleBtnDownMouseOut(){
	VSA_scrollAreas[this.index].scrolling = false;
}

function VSA_scrollIt(){
	this.scrollContent.scrollTop = this.scrollFactor * ((this.scrollslider.offsetTop + this.scrollslider.offsetHeight/2) - this.scrollButtonHeight - this.scrollslider.offsetHeight/2);
}

function VSA_scrollUp(){
	if (this.scrollingLimit > 0){
		this.scrollingLimit--;
		if (this.scrollingLimit == 0) this.scrolling = false;
	}
	if (!this.scrolling) return;
	if ( this.scrollContent.scrollTop - this.scrollStep > 0){
		this.scrollContent.scrollTop -= this.scrollStep;
		this.scrollslider.style.top = 1 / this.scrollFactor * Math.abs(this.scrollContent.scrollTop) + this.scrollButtonHeight + "px";
	}else{
		this.scrollContent.scrollTop = "0";
		this.scrollslider.style.top = this.scrollButtonHeight + "px";
		return;
	}
	setTimeout("VSA_Ext_scrollUp(" + this.index + ")", 30);
}

function VSA_Ext_scrollUp(index){
	VSA_scrollAreas[index].scrollUp();
}

function VSA_scrollDown(){
	if (this.scrollingLimit > 0){
		this.scrollingLimit--;
		if (this.scrollingLimit == 0) this.scrolling = false;
	}
	if (!this.scrolling) return;


	this.scrollContent.scrollTop += this.scrollStep;
	this.scrollslider.style.top =  1 / this.scrollFactor * Math.abs(this.scrollContent.scrollTop) + this.scrollButtonHeight + "px";

	if (this.scrollContent.scrollTop >= (this.scrollContent.scrollHeight - this.scrollContent.offsetHeight)){
		this.scrollContent.scrollTop = (this.scrollContent.scrollHeight - this.scrollContent.offsetHeight);
		this.scrollslider.style.top = this.scrollbar.offsetHeight - this.scrollButtonHeight - this.scrollslider.offsetHeight + "px";
		return;
	}

	setTimeout("VSA_Ext_scrollDown(" + this.index + ")", 30);
}

function VSA_Ext_scrollDown(index){
	VSA_scrollAreas[index].scrollDown();
}

function VSA_handleMouseMove(evt){
	var sa = VSA_scrollAreas[((document.all && !window.opera) ? this.index : document.documentElement.scrollAreaIndex)];
	var posy = 0;
	if (!evt) var evt = window.event;
	
	if (evt.pageY)
		posy = evt.pageY;
	else if (evt.clientY)
		posy = evt.clientY;
			
		if (document.all && !window.opera){
			if(!document.addEventListener) {
				posy += document.documentElement.scrollTop;
			}
		}

	var iNewY = posy - sa.iOffsetY - getRealTop(sa.scrollbar) - sa.scrollButtonHeight;
		iNewY += sa.scrollButtonHeight;
		
	if (iNewY < sa.scrollButtonHeight)
		iNewY = sa.scrollButtonHeight;
	if (iNewY > (sa.scrollbar.offsetHeight - sa.scrollButtonHeight) - sa.scrollslider.offsetHeight)
		iNewY = (sa.scrollbar.offsetHeight - sa.scrollButtonHeight) - sa.scrollslider.offsetHeight;

	sa.scrollslider.style.top = iNewY + "px";

	sa.scrollIt();
}

function VSA_handleSliderMouseDown(evt){
	if (!(document.uniqueID && document.compatMode && !window.XMLHttpRequest)){
		document.onselectstart = function() { return false; }
		document.onmousedown = function() { return false; }
	}

	var sa = VSA_scrollAreas[this.index];
	if (document.all && !window.opera){
		sa.scrollslider.setCapture()
		sa.iOffsetY = event.offsetY;
		sa.scrollslider.onmousemove = VSA_handleMouseMove;
		if(VSA_touchFlag) {
			sa.scrollslider.addEventListener("touchmove", touchHandler, true);
		}
	}else{
		if(window.opera){
			sa.iOffsetY = event.offsetY;
		}else{
			sa.iOffsetY = evt.layerY;
		}
		document.documentElement.scrollAreaIndex = sa.index;
		document.documentElement.addEventListener("mousemove", VSA_handleMouseMove, true);
		document.documentElement.addEventListener("mouseup", VSA_handleSliderMouseUp, true);
		if(VSA_touchFlag) {
			document.documentElement.addEventListener("touchmove", touchHandler, true);
			document.documentElement.addEventListener("touchend", touchHandler, true);
		}
	}
	return false;
}

function VSA_handleSliderMouseUp(){
	if (!(document.uniqueID && document.compatMode && !window.XMLHttpRequest)){
		document.onmousedown = null;
		document.onselectstart = null;
	}

	if (document.all && !window.opera){
		var sa = VSA_scrollAreas[this.index];
		sa.scrollslider.onmousemove = null;
		sa.scrollslider.releaseCapture();
		sa.scrollIt();
	}else{
		var sa = VSA_scrollAreas[document.documentElement.scrollAreaIndex];
		document.documentElement.removeEventListener("mousemove", VSA_handleMouseMove, true);
		document.documentElement.removeEventListener("mouseup", VSA_handleSliderMouseUp, true);
		if(VSA_touchFlag) {
			document.documentElement.removeEventListener("touchmove", touchHandler, true);
			document.documentElement.removeEventListener("touchend", touchHandler, true);
		}
		sa.scrollIt();
	}
	return false;
}

function VSA_handleResize(){
	if (VSA_resizeTimer){
		clearTimeout(VSA_resizeTimer);
		VSA_resizeTimer = 0;
	}
	VSA_resizeTimer = setTimeout("VSA_performResizeEvent()", 100);
}

function VSA_performResizeEvent(){
	for (var i=0; i<VSA_scrollAreas.length; i++)
		VSA_scrollAreas[i].createScrollBar();
}
function VSA_handleMouseWheel(event){
	if (this.index != null) {
		var sa = VSA_scrollAreas[this.index];
		if (sa.scrollbar == null) return;
		sa.scrolling = true;
		sa.scrollingLimit = sa.wheelSensitivity;

		var delta = 0;
		if (!event) /* For IE. */
			event = window.event;
		if (event.wheelDelta) { /* IE/Opera. */
			delta = event.wheelDelta/120;
			/*if (window.opera) delta = -delta;*/
		} else if (event.detail) { /* Mozilla case. */
			delta = -event.detail/3;
		}

		if (delta && sa.element.over){
			if (delta > 0){
				sa.scrollUp();
			} else{
				sa.scrollDown();
			}
			if (event.preventDefault){
				event.preventDefault();
			}
			event.returnValue = false;
		}
	}
}

function VSA_handleSelectStart(){
	event.returnValue = false;
}

function VSA_handleScrollbarClick(evt){
	var sa = VSA_scrollAreas[this.index];
	var offsetY = (document.all ? event.offsetY : evt.layerY);

	if (offsetY < (sa.scrollButtonHeight + sa.scrollslider.offsetHeight/2))
		sa.scrollslider.style.top = sa.scrollButtonHeight + "px";
	else if (offsetY > (sa.scrollbar.offsetHeight - sa.scrollButtonHeight - sa.scrollslider.offsetHeight))
		sa.scrollslider.style.top = sa.scrollbar.offsetHeight - sa.scrollButtonHeight - sa.scrollslider.offsetHeight + "px";
	else{
		sa.scrollslider.style.top = offsetY + sa.scrollButtonHeight - sa.scrollslider.offsetHeight/2 + "px";
	}
	sa.scrollIt();
}

function VSA_handleOnScroll(){
	//event.srcElement.doScroll("pageUp");
}

//--- common functions ----

function VSA_getElements(attrValue, tagName, ownerNode, attrName){  //get Elements By Attribute Name
	if (!tagName) tagName = "*";
	if (!ownerNode) ownerNode = document;
	if (!attrName) attrName = "name";
	var result = [];
	var nl = ownerNode.getElementsByTagName(tagName);
	for (var i=0; i<nl.length; i++){
	//	if (nl.item(i).getAttribute(attrName) == attrValue)
//		result.push(nl.item(i));
		if (nl.item(i).className.indexOf(attrValue) != -1)
		result.push(nl.item(i));
	}
	return result;
}

function getRealTop(obj){
	var posTop = 0;
	while (obj.offsetParent) {
		posTop += obj.offsetTop;
		obj = obj.offsetParent;
	}
	return posTop;
}

//custom forms
var _selectHeight = 14;
var all_selects = false;
var active_select = null;
var selectText = "please select";

function initCustomForms() {
	getElements();
	separateElements();
	replaceRadios();
	replaceCheckboxes();
	//replaceSelects();

	var _selects = document.getElementsByTagName('select');
	
	    var _SelctClassName = [];
	if (_selects) {
		for (var i = 0; i < _selects.length; i++) {
			if (_selects[i].className != '' && _selects[i].className != 'outtaHere')
				_SelctClassName[i] = ' drop-'+_selects[i].className;
		}
		for (var i = 0; i < _SelctClassName.length; i++) {
			var _selectDrop = document.getElementById('optionsDiv'+i);
			if (_selectDrop) {
				if (_SelctClassName[i]) 
					_selectDrop.className += _SelctClassName[i];
			}
		}
	}
}

function refreshCustomForms() {
	// remove prevously created elements
	if(window.inputs) {
		for(var i = 0; i < checkboxes.length; i++) {
			if(checkboxes[i].checked) {checkboxes[i]._ca.className = "checkboxAreaChecked";}
			else {checkboxes[i]._ca.className = "checkboxArea";}
		}
		for(var i = 0; i < radios.length; i++) {
			if(radios[i].checked) {radios[i]._ra.className = "radioAreaChecked";}
			else {radios[i]._ra.className = "radioArea";}
		}
		for(var i = 0; i < selects.length; i++) {
			var newText = document.createElement('div');
			if (selects[i].options[selects[i].selectedIndex].title.indexOf('image') != -1) {
				newText.innerHTML = '<img src="'+selects[i].options[selects[i].selectedIndex].title+'" alt="" />';
				newText.innerHTML += '<span>'+selects[i].options[selects[i].selectedIndex].text+'</span>';
			} else {
				newText.innerHTML = selects[i].options[selects[i].selectedIndex].text;
			}
			document.getElementById("mySelectText"+i).innerHTML = newText.innerHTML;
		}
	}
}

// getting all the required elements
function getElements() {
	// remove prevously created elements
	if(window.inputs) {
		for(var i = 0; i < inputs.length; i++) {
			inputs[i].className = inputs[i].className.replace('outtaHere','');
			if(inputs[i]._ca) inputs[i]._ca.parentNode.removeChild(inputs[i]._ca);
			else if(inputs[i]._ra) inputs[i]._ra.parentNode.removeChild(inputs[i]._ra);
		}
		for(i = 0; i < selects.length; i++) {
			selects[i].replaced = null;
			selects[i].className = selects[i].className.replace('outtaHere','');
			selects[i]._optionsDiv._parent.parentNode.removeChild(selects[i]._optionsDiv._parent);
			selects[i]._optionsDiv.parentNode.removeChild(selects[i]._optionsDiv);
		}
	}

	// reset state
	inputs = new Array();
	selects = new Array();
	labels = new Array();
	radios = new Array();
	radioLabels = new Array();
	checkboxes = new Array();
	checkboxLabels = new Array();
	for (var nf = 0; nf < document.getElementsByTagName("form").length; nf++) {
		for(var nfi = 0; nfi < document.forms[nf].getElementsByTagName("input").length; nfi++) {inputs.push(document.forms[nf].getElementsByTagName("input")[nfi]);}
		for(var nfl = 0; nfl < document.forms[nf].getElementsByTagName("label").length; nfl++) {labels.push(document.forms[nf].getElementsByTagName("label")[nfl]);}
		for(var nfs = 0; nfs < document.forms[nf].getElementsByTagName("select").length; nfs++) {selects.push(document.forms[nf].getElementsByTagName("select")[nfs]);}
	}
}

// separating all the elements in their respective arrays
function separateElements() {
	var r = 0; var c = 0; var t = 0; var rl = 0; var cl = 0; var tl = 0; var b = 0;
	for (var q = 0; q < inputs.length; q++) {
		if(inputs[q].type == "radio") {
			radios[r] = inputs[q]; ++r;
			for(var w = 0; w < labels.length; w++) {
				if((inputs[q].id) && labels[w].htmlFor == inputs[q].id)
				{
					radioLabels[rl] = labels[w];
					++rl;
				}
			}
		}
		if(inputs[q].type == "checkbox") {
			checkboxes[c] = inputs[q]; ++c;
			for(var w = 0; w < labels.length; w++) {
				if((inputs[q].id) && (labels[w].htmlFor == inputs[q].id))
				{
					checkboxLabels[cl] = labels[w];
					++cl;
				}
			}
		}
	}
}

//replacing radio buttons
function replaceRadios() {
	for (var q = 0; q < radios.length; q++) {
		//radios[q].className += " outtaHere";
		var radioArea = document.createElement("div");
		if(radios[q].checked) {
			radioArea.className = "radioAreaChecked";
		}
		else
		{
			radioArea.className = "radioArea";
		}
		radioArea.id = "myRadio" + q;
		radios[q].parentNode.insertBefore(radioArea, radios[q]);
		radios[q]._ra = radioArea;

		radioArea.onclick = new Function('rechangeRadios('+q+')');
		if (radioLabels[q])
		{
			radioLabels[q].onclick = new Function('rechangeRadios('+q+')');
		}
	}
	return true;
}

//checking radios
function checkRadios(who) {
	var what = radios[who]._ra;
	for(var q = 0; q < radios.length; q++) {
		if((radios[q]._ra.className == "radioAreaChecked")&&(radios[q]._ra.nextSibling.name == radios[who].name))
		{
			radios[q]._ra.className = "radioArea";
		}
	}
	what.className = "radioAreaChecked";
}

//changing radios
function changeRadios(who) {
	if(radios[who].checked) {
		for(var q = 0; q < radios.length; q++) {
			if(radios[q].name == radios[who].name) {
				radios[q].checked = false;
			} 
			radios[who].checked = true; 
			checkRadios(who);
		}
	}
}

//rechanging radios
function rechangeRadios(who) {
	if(!radios[who].checked) {
		for(var q = 0; q < radios.length; q++) {
			if(radios[q].name == radios[who].name)	{
				radios[q].checked = false; 
			}
			radios[who].checked = true; 
			checkRadios(who);
		}
	}
}

//replacing checkboxes
function replaceCheckboxes() {
	for (var q = 0; q < checkboxes.length; q++) {
		checkboxes[q].className += " outtaHere";
		var checkboxArea = document.createElement("div");
		if(checkboxes[q].checked) {
			checkboxArea.className = "checkboxAreaChecked";
		}
		else {
			checkboxArea.className = "checkboxArea";
		}
		checkboxArea.id = "myCheckbox" + q;
		checkboxes[q].parentNode.insertBefore(checkboxArea, checkboxes[q]);
		checkboxes[q]._ca = checkboxArea;
		checkboxArea.onclick = checkboxArea.onclick2 = new Function('rechangeCheckboxes('+q+')');
		if (checkboxLabels[q]) {
			checkboxLabels[q].onclick = new Function('changeCheckboxes('+q+')');
		}
		checkboxes[q].onkeydown = checkEvent;
	}
	return true;
}

//checking checkboxes
function checkCheckboxes(who, action) {
	var what = checkboxes[who]._ca;
	if(action == true) {
		what.className = "checkboxAreaChecked";
		what.checked = true;
	}
	if(action == false) {
		what.className = "checkboxArea";
		what.checked = false;
	}
}

//changing checkboxes
function changeCheckboxes(who) {
	if(checkboxes[who].checked) {
		checkCheckboxes(who, false);
	}
	else {
		checkCheckboxes(who, true);
	} 
}

//rechanging checkboxes
function rechangeCheckboxes(who) {
	var tester = false;
	if(checkboxes[who].checked == true) {
		tester = false;
	}
	else {
		tester = true;
	}
	checkboxes[who].checked = tester;
	checkCheckboxes(who, tester);
}

//check event
function checkEvent(e) {
	if (!e) var e = window.event;
	if(e.keyCode == 32) {for (var q = 0; q < checkboxes.length; q++) {if(this == checkboxes[q]) {changeCheckboxes(q);}}} //check if space is pressed
}


function replaceSelects() {
	for(var q = 0; q < selects.length; q++) {
		if (!selects[q].replaced && selects[q].offsetWidth) {
			selects[q]._number = q;
			//create and build div structure
			var selectArea = document.createElement("div");
			var left = document.createElement("span");
			left.className = "left";
			selectArea.appendChild(left);

			var disabled = document.createElement("span");
			disabled.className = "disabled";
			selectArea.appendChild(disabled);

			selects[q]._disabled = disabled;
			var center = document.createElement("span");
			var button = document.createElement("a");
			var text = document.createTextNode(selectText);
			center.id = "mySelectText"+q;

			var stWidth = selects[q].offsetWidth;
			selectArea.style.width = stWidth + "px";
			if (selects[q].parentNode.className.indexOf("type2") != -1){
				button.href = "javascript:showOptions("+q+",true)";
			} else {
				button.href = "javascript:showOptions("+q+",false)";
			}
			button.className = "selectButton";
			selectArea.className = "selectArea";

			selectArea.className += " " + selects[q].className;
			selectArea.id = "sarea"+q;
			center.className = "center";
			center.appendChild(text);
			selectArea.appendChild(center);
			selectArea.appendChild(button);

			//hide the select field
			selects[q].className += " outtaHere";
			//insert select div
			selects[q].parentNode.insertBefore(selectArea, selects[q]);
			//build & place options div

			var optionsDiv = document.createElement("div");
			var optionsList = document.createElement("ul");
			optionsDiv.innerHTML += "<div class='select-top'><div></div></div>";
			optionsDiv.appendChild(optionsList);

			selects[q]._optionsDiv = optionsDiv;
			selects[q]._options = optionsList;

			optionsDiv.style.width = stWidth + "px";
			optionsDiv._parent = selectArea;

			optionsDiv.className = "optionsDivInvisible";
			optionsDiv.id = "optionsDiv"+q;


			populateSelectOptions(selects[q]);
			optionsDiv.innerHTML += "<div class='select-bottom'><div class='select-bottom-left'></div><div class='select-bottom-right'></div></div>";
			document.body.appendChild(optionsDiv);
			selects[q].replaced = true;
		}
		all_selects = true;
	}
}

//collecting select options
function populateSelectOptions(me) {
	me._options.innerHTML = "";
	
	for(var w = 0; w < me.options.length; w++) {
		
		var optionHolder = document.createElement('li');
		var optionLink = document.createElement('a');
		var optionTxt;
		if (me.options[w].title.indexOf('image') != -1) {
			optionTxt = document.createElement('img');
			optionSpan = document.createElement('span');
			optionTxt.src = me.options[w].title;
			optionSpan = document.createTextNode(me.options[w].text);
		} else {
			optionTxt = document.createTextNode(me.options[w].text);
		}
		
		optionLink.href = "javascript:showOptions("+me._number+"); selectMe('"+me.id+"',"+w+","+me._number+");";
		if (me.options[w].title.indexOf('image') != -1) {
			optionLink.appendChild(optionTxt);
			optionLink.appendChild(optionSpan);
		} else {
			optionLink.appendChild(optionTxt);
		}
		optionHolder.appendChild(optionLink);
		me._options.appendChild(optionHolder);
		//check for pre-selected items
		if(me.options[w].selected) {
			selectMe(me.id,w,me._number);
		}
	}
	if (me.disabled) {
		me._disabled.style.display = "block";
	}
	else {
		me._disabled.style.display = "none";
	}
}

//selecting me
function selectMe(selectFieldId,linkNo,selectNo) {
	selectField = selects[selectNo];
	for(var k = 0; k < selectField.options.length; k++) {
		if(k==linkNo) {
			selectField.options[k].selected = true;
		}
		else {
			selectField.options[k].selected = false;
		}
	}
	
	//show selected option
	textVar = document.getElementById("mySelectText"+selectNo);
	var newText;
	var optionSpan;
	if (selectField.options[linkNo].title.indexOf('image') != -1) {
		newText = document.createElement('img');
		newText.src = selectField.options[linkNo].title;
		optionSpan = document.createElement('span');
		optionSpan = document.createTextNode(selectField.options[linkNo].text);
	} else {
		newText = document.createTextNode(selectField.options[linkNo].text);
	}
	if (selectField.options[linkNo].title.indexOf('image') != -1) {
		if (textVar.childNodes.length > 1) textVar.removeChild(textVar.childNodes[0]);
		textVar.replaceChild(newText, textVar.childNodes[0]);
		textVar.appendChild(optionSpan);
	} else {
		if (textVar.childNodes.length > 1) textVar.removeChild(textVar.childNodes[0]);
		textVar.replaceChild(newText, textVar.childNodes[0]);
	}
	if (all_selects && selectField.onchange) {
		eval(selectField.onchange());
	}
}
//showing options
function showOptions(g) {
		_elem = document.getElementById("optionsDiv"+g);
		var divArea = document.getElementById("sarea"+g);
		if (active_select && active_select != _elem) {
			active_select.className = active_select.className.replace('optionsDivVisible',' optionsDivInvisible');
			active_select.style.height = "auto";
		}
		if(_elem.className.indexOf("optionsDivInvisible") != -1) {
			_elem.style.left = "-9999px";
			_elem.style.top = findPosY(divArea) + _selectHeight + 'px';
			_elem.className = _elem.className.replace('optionsDivInvisible','');
			_elem.className += " optionsDivVisible";
			/*if (_elem.offsetHeight > 200)
			{
				_elem.style.height = "200px";
			}*/
			_elem.style.left = findPosX(divArea) + 'px';
			
			active_select = _elem;
			if(document.documentElement)
			{
				document.documentElement.onclick = hideSelectOptions;
			}
			else
			{
				window.onclick = hideSelectOptions;
			}
		}
		else if(_elem.className.indexOf("optionsDivVisible") != -1) {
			_elem.style.height = "auto";
			_elem.className = _elem.className.replace('optionsDivVisible','');
			_elem.className += " optionsDivInvisible";
		}
		
		// for mouseout
		/*_elem.timer = false;
		_elem.onmouseover = function() {
			if (this.timer) clearTimeout(this.timer);
		}
		_elem.onmouseout = function() {
			var _this = this;
			this.timer = setTimeout(function(){
				_this.style.height = "auto";
				_this.className = _this.className.replace('optionsDivVisible','');
				if (_elem.className.indexOf('optionsDivInvisible') == -1)
					_this.className += " optionsDivInvisible";
			},200);
		}*/
}

function hideSelectOptions(e)
{
	if(active_select)
	{
		if(!e) e = window.event;
		var _target = (e.target || e.srcElement);
		if(isElementBefore(_target,'selectArea') == 0 && isElementBefore(_target,'optionsDiv') == 0)
		{
			active_select.className = active_select.className.replace('optionsDivVisible', '');
			active_select.className = active_select.className.replace('optionsDivInvisible', '');
			active_select.className += " optionsDivInvisible";
			active_select = false;

			if(document.documentElement)
			{
				document.documentElement.onclick = function(){};
			}
			else
			{
				window.onclick = null;
			}
		}
	}
}

function isElementBefore(_el,_class)
{
	var _parent = _el;	
	do
	{
		_parent = _parent.parentNode;
	}
	while(_parent && _parent.className != null && _parent.className.indexOf(_class) == -1)
	
	if(_parent.className && _parent.className.indexOf(_class) != -1)
	{
		return 1;
	}
	else
	{
		return 0;
	}
	
}

function findPosY(obj) {
	return $(obj).offset().top;
}
function findPosX(obj) {
	return $(obj).offset().left;
}

/* IE6 Hover fix module */
var ieHover = {
	lazyMode: true,
	init: function(){
		this.setDefaults();
		return this;
	},
	setDefaults: function() {
		this.fixActive = /MSIE 6/.test(navigator.userAgent);
		if(this.fixActive) {
			this.hoverEvents = []; this.hoverQueue = [];
			this.activators = {
				onhover:{on:'onmouseenter', off:'onmouseleave'},
				onactive:{on:'onmousedown', off:'onmouseup'}
			}
			window.attachEvent('onload', this.bind(this.domReady,this));
			window.attachEvent('onunload', this.bind(this.unhookHoverEvents,this));
		}
	},
	domReady: function() {
		this.pageReady = true;
		if(this.lazyMode) {
			this.processStylesheets();
		}
		if(this.hoverQueue.length) {
			for(var i = 0; i < this.hoverQueue.length; i++) {
				this.doFix(this.hoverQueue[i].s,this.hoverQueue[i].c);
			}
		}
	},
	processStylesheets: function() {
		var sheets = document.styleSheets, len = sheets.length;
		for(var i = 0; i < len; i++) { this.parseStylesheet(sheets[i]); }
	},
	parseStylesheet: function(sheet) {
		if(sheet.imports) {
			try {
				var imports = sheet.imports, l = imports.length;
				for(var i=0; i<l; i++) this.parseStylesheet(sheet.imports[i]);
			} catch(e){}
		}
		try {
			var rules = (this.currentSheet = sheet).rules, l = rules.length;
			for(var j=0; j<l; j++) this.parseCSSRule(rules[j]);
		} catch(e){}
	},
	parseCSSRule: function(rule) {
		var select = rule.selectorText, style = rule.style.cssText;
		if(!/(^|\s)(([^a]([^ ]+)?)|(a([^#.][^ ]+)+)):(hover|active)/i.test(select) || !style) return;
		var pseudo = select.replace(/[^:]+:([a-z-]+).*/i, 'on$1');
		var newSelect = select.replace(/(\.([a-z0-9_-]+):[a-z]+)|(:[a-z]+)/gi, '.$2' + pseudo);
		var className = (/\.([a-z0-9_-]*on(hover|active))/i).exec(newSelect)[1];
		var affected = select.replace(/:(hover|active).*$/, '');
		var elements = this.parseSelector(affected);
		if(!elements.length) return;
		this.currentSheet.addRule(newSelect, style);
		for(var i=0; i < elements.length; i++) {
			this.addHoverElement(elements[i], className, this.activators[pseudo]);
		}
	},
	fix: function(selector, className) {
		if(this.fixActive) {
			if(this.pageReady) {
				this.doFix(selector,className)
			} else {
				this.hoverQueue.push({s:selector,c:className});
			}
		}
	},
	doFix: function(selector, className) {
		if(this.fixActive && typeof selector === 'string') {
			var elements = this.parseSelector(selector);
			for(var i=0; i < elements.length; i++) {
				this.addHoverElement(elements[i], className || 'hover', this.activators['onhover']);
			}
		}
	},
	addHoverElement: function(node, className, events) {
		if(!node.hovers) node.hovers = {};
		if(node.hovers[className]) return;
		node.hovers[className] = true;
		this.hookHoverEvent(node, events.on, function() { node.className += ' ' + className; });
		this.hookHoverEvent(node, events.off, function() { node.className = node.className.replace(new RegExp('\\s+'+className, 'g'),''); });
	},
	hookHoverEvent: function(node, type, handler) {
		node.attachEvent(type, handler);
		this.hoverEvents[this.hoverEvents.length] = {
			node:node, type:type, handler:handler
		};
	},
	unhookHoverEvents: function() {
		for(var e,i=0; i < this.hoverEvents.length; i++) {
			e = this.hoverEvents[i];
			e.node.detachEvent(e.type, e.handler);
		}
	},
	parseSelector: (function () {
		var g = /^([^#.>`]*)(#|\.|\>|\`)(.+)$/;
		function parseSelector(a, b) {
			var c = a.split(/\s*\,\s*/);
			var d = [];
			for (var i = 0; i < c.length; i++) {
				d = d.concat(doParse(c[i], b))
			};
			return d
		};
		function doParse(a, b, c) {
			a = a.replace(" ", "`");
			var d = a.match(g);
			var e, listNodes, listSubNodes, subselector, i, limit;
			var f = [];
			if (d == null) {
				d = [a, a]
			};
			if (d[1] == "") {
				d[1] = "*"
			};
			if (c == null) {
				c = "`"
			};
			if (b == null) {
				b = document
			};
			switch (d[2]) {
			case "#":
				subselector = d[3].match(g);
				if (subselector == null) {
					subselector = [null, d[3]]
				};
				e = document.getElementById(subselector[1]);
				if (e == null || (d[1] != "*" && !matchNodeNames(e, d[1]))) {
					return f
				};
				if (subselector.length == 2) {
					f.push(e);
					return f
				};
				return doParse(subselector[3], e, subselector[2]);
			case ".":
				if (c != ">") {
					listNodes = getElementsByTagName(b, d[1])
				} else {
					listNodes = b.childNodes
				};
				for (i = 0, limit = listNodes.length; i < limit; i++) {
					e = listNodes[i];
					if (e.nodeType != 1) {
						continue
					};
					subselector = d[3].match(g);
					if (subselector != null) {
						if (e.className == null || e.className.match("(\\s|^)" + subselector[1] + "(\\s|$)") == null) {
							continue
						};
						listSubNodes = doParse(subselector[3], e, subselector[2]);
						f = f.concat(listSubNodes)
					} else if (e.className != null && e.className.match("(\\s|^)" + d[3] + "(\\s|$)") != null) {
						f.push(e)
					}
				};
				return f;
			case ">":
				if (c != ">") {
					listNodes = getElementsByTagName(b, d[1])
				} else {
					listNodes = b.childNodes
				};
				for (i = 0, limit = listNodes.length; i < limit; i++) {
					e = listNodes[i];
					if (e.nodeType != 1) {
						continue
					};
					if (!matchNodeNames(e, d[1])) {
						continue
					};
					listSubNodes = doParse(d[3], e, ">");
					f = f.concat(listSubNodes)
				};
				return f;
			case "`":
				listNodes = getElementsByTagName(b, d[1]);
				for (i = 0, limit = listNodes.length; i < limit; i++) {
					e = listNodes[i];
					listSubNodes = doParse(d[3], e, "`");
					f = f.concat(listSubNodes)
				};
				return f;
			default:
				if (c != ">") {
					listNodes = getElementsByTagName(b, d[1])
				} else {
					listNodes = b.childNodes
				};
				for (i = 0, limit = listNodes.length; i < limit; i++) {
					e = listNodes[i];
					if (e.nodeType != 1) {
						continue
					};
					if (!matchNodeNames(e, d[1])) {
						continue
					};
					f.push(e)
				};
				return f
			}
		};
		function getElementsByTagName(a, b) {
			if (b == "*" && a.all != null) {
				return a.all
			};
			return a.getElementsByTagName(b)
		};
		function matchNodeNames(a, b) {
			if (b == "*") {
				return true
			};
			return a.nodeName.toLowerCase().replace("html:", "") == b.toLowerCase()
		};
		return parseSelector
	}()),
	bind: function(fn, scope, args) {
		return function() {
			return fn.apply(scope, args || arguments);
		}
	}
}.init();

jcf = {};
jcf.modules = {};
jcf.baseOptions = {
	hiddenClass:'outtaHere',
	replaceAll:true
}

// advanced replacer class
jcf.customForms = function(opt) {
	this.options = jcf.baseOptions;
	jcf.lib.extend(this.options, opt);
}
jcf.customForms.prototype.replace = function(obj, opt) {
	for(var k in jcf.modules) {
		var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector);
		for(var i = 0; i<els.length; i++) {
			new jcf.modules[k]({
				replaces:els[i]
			});
		}
	}
}
jcf.setBaseModule = function(obj) {
	jcf.customControl = function(opt){
		this.options = {
			labelActiveClass: 'jcf-label-active',
			focusClass:'jcf-focus',
			foo:'bar'
		}
		jcf.lib.extend(this.options, opt);
		this.init();
	}
	for(var p in obj) {
		jcf.customControl.prototype[p] = obj[p];
	}
}
jcf.addModule = function(obj) {
	if(obj.name){
		// create new module proto class
		jcf.modules[obj.name] = function(){
			jcf.modules[obj.name].superclass.constructor.apply(this, arguments);
		}
		jcf.lib.inherit(jcf.modules[obj.name], jcf.customControl);
		for(var p in obj) {
			jcf.modules[obj.name].prototype[p] = obj[p]
		}

		// on create module
		jcf.modules[obj.name].prototype.onCreateModule();

		// make callback for exciting modules
		for(var mod in jcf.modules) {
			if(jcf.modules[mod] != jcf.modules[obj.name]) {
				jcf.modules[mod].prototype.onModuleAdded(jcf.modules[obj.name]);
			}
		}
	}
}

// custom control base class
jcf.setBaseModule({
    init: function () {
        this.initOptions();
        this.realElement = this.options.replaces;
        if (this.realElement && !$(this.realElement).hasClass('no-replace')) {
            this.replaceObject();
        } else if ($(this.realElement).hasClass('no-replace')) {
            $(this.realElement).removeClass('outtaHere');
        }
    },
    initOptions: function () {

    },
    createWrapper: function () {
        this.fakeElement = document.createElement('div');
        this.fakeElement.jcf = this;
        this.realElement.jcf = this;
        this.labelFor = jcf.lib.getLabelFor(this.realElement);
        jcf.lib.disableTextSelection(this.fakeElement);
        jcf.lib.addClass(this.realElement, jcf.baseOptions.hiddenClass);
    },
    initEvents: function () {
        jcf.lib.event.add(this.realElement, 'click', this.onClick);
        jcf.lib.event.add(this.realElement, 'focus', this.onFocus);
        jcf.lib.event.add(this.realElement, 'blur', this.onBlur);

        jcf.lib.event.add(this.fakeElement, 'click', this.onFakeClick);
        jcf.lib.event.add(this.fakeElement, 'mousedown', this.onFakeMouseDown);
        jcf.lib.event.add(this.fakeElement, 'mouseup', this.onFakeMouseUp);

        if (this.labelFor) {
            this.labelFor.jcf = this;
            jcf.lib.event.add(this.labelFor, 'click', this.onFakeClick);
            jcf.lib.event.add(this.labelFor, 'mousedown', this.onFakeMouseDown);
            jcf.lib.event.add(this.labelFor, 'mouseup', this.onFakeMouseUp);
        }
    },
    setupWrapper: function () {
        // implement in subclass
    },
    refreshState: function () {
        // implement in subclass
    },
    replaceObject: function () {
        /*if ($(this.realElement).hasClass('no-replace')) {
        $(this.realElement).removeClass('outtaHere');
        return;
        }*/
        this.createWrapper();
        this.initEvents();
        this.setupWrapper();
    },
    onClick: function () {
        this.jcf.refreshState();
    },
    onFocus: function () {
        clearTimeout(this.jcf.focusTimer);
        this.jcf.fakeElement.mouseDownFlag = false;
        if (!this.jcf.realElement.disabled) {
            jcf.lib.addClass(this.jcf.fakeElement, this.jcf.options.focusClass);
        }
    },
    onBlur: function () {
        var _this = this;
        this.jcf.focusTimer = setTimeout(function () {
            if (!_this.jcf.fakeElement.mouseDownFlag) {
                jcf.lib.removeClass(_this.jcf.fakeElement, _this.jcf.options.focusClass);
            }
        }, 10);
    },
    onFakeClick: function () {
        this.jcf.realElement.focus();
    },
    onFakeMouseDown: function () {
        this.jcf.fakeElement.mouseDownFlag = true;
        return false;
    },
    onFakeMouseUp: function () {
        this.jcf.fakeElement.mouseDownFlag = false;
    },
    onCreateModule: function () {
        // implement in subclass
    },
    onModuleAdded: function (module) {
        // implement in subclass
    },
    onControlReady: function () {
        // implement in subclass
    }
});










// custom forms util library
jcf.lib = {
	bind: function(func, scope){
		var _function = func;
		return function() {
			return _function.apply(scope, arguments);
		}
	},
	browser: (function() {
		var rwebkit = /(webkit)[ \/]([\w.]+)/,
		ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
		rmsie = /(msie) ([\w.]+)/,
		rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/;
		var ua = navigator.userAgent.toLowerCase();
		var match = rwebkit.exec( ua ) || ropera.exec( ua ) || rmsie.exec( ua ) || ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || [];
		var res = {};
		res[match[1]] = true;
		res.version = match[2] || "0";
		return res;
	})(),
	getOffset: function(element) {
		var el = element;
		var valueT = 0, valueL = 0;
		if (element.offsetParent) {
			do {
				// hello reflow
				valueT += element.offsetTop  || 0;
				valueL += element.offsetLeft || 0;
				if(element != document.body && element != document.body.parentNode) {
					valueT -= element.scrollTop  || 0;
					valueL -= element.scrollLeft  || 0;
				}
				valueT += parseInt(jcf.lib.getStyle(element,'borderTopWidth')) || 0;
				valueL += parseInt(jcf.lib.getStyle(element,'borderLeftWidth')) || 0;
				element = element.offsetParent;
			} while (element);
		}
		return {top:valueT, left:valueL};
	},
	getStyle: function(el, prop) {
		if (document.defaultView && document.defaultView.getComputedStyle) {
			return document.defaultView.getComputedStyle(el, null)[prop];
		} else if (el.currentStyle) {
			return el.currentStyle[prop];
		} else {
			return el.style[prop];
		}
	},
	getParent: function(obj, selector) {
		while(obj.parentNode && obj.parentNode != document.body) {
			if(obj.parentNode.tagName.toLowerCase() == selector.toLowerCase()) {
				return obj.parentNode;
			}
			obj = obj.parentNode;
		}
		return false;
	},
	isParent: function(child, parent) {
		while(child.parentNode) {
			if(child.parentNode === parent) {
				return true;
			}
			child = child.parentNode;
		}
		return false;
	},
	getLabelFor: function(object) {
		if(jcf.lib.getParent(object,'label')) {
			return object.parentNode;
		} else if(object.id && object.id.length) {
			return jcf.lib.queryBySelector('label[for=' + object.id + ']')[0];
		}
	},
	disableSelection: function() {
		document.onselectstart = function(){return false}
	},
	enableSelection: function() {
		document.onselectstart = null
	},
	disableTextSelection: function(el){
		if(el.setProperty) {
			el.setProperty("unselectable","on");
		}
		el.style.MozUserSelect = 'none';
		el.style.KhtmlUserSelect = 'none';
	},
	queryBySelector: function(selector, scope){
		return document.querySelectorAll ? (scope || document).querySelectorAll(selector) : jcf.lib.getElementsBySelector(selector, scope);
	},
	prevSibling: function(node) {
		while(node = node.previousSibling) if(node.nodeType == 1) break;
		return node;
	},
	nextSibling: function(node) {
		while(node = node.nextSibling) if(node.nodeType == 1) break;
		return node;
	},
	fireEvent: function(element,event) {
		if (document.createEventObject){
			var evt = document.createEventObject();
			return element.fireEvent('on'+event,evt)
		}
		else{
			var evt = document.createEvent('HTMLEvents');
			evt.initEvent(event, true, true );
			return !element.dispatchEvent(evt);
		}
	},
	isParent: function(p, c) {
		while(c.parentNode) {
			if(p == c) {
				return true;
			}
			c = c.parentNode;
		}
		return false;
	},
	inherit: function(Child, Parent) {
		var F = function() { }
		F.prototype = Parent.prototype
		Child.prototype = new F()
		Child.prototype.constructor = Child
		Child.superclass = Parent.prototype
	},
	extend: function(obj1,obj2) {
		for(var prop in obj2) {
			obj1[prop] = obj2[prop];
		}
	},
	hasClass: function (obj,cname) {
		return (obj.className ? obj.className.match(new RegExp('(\\s|^)'+cname+'(\\s|$)')) : false);
	},
	addClass: function (obj,cname) {
		if (!this.hasClass(obj,cname)) obj.className += " "+cname;
	},
	removeClass: function (obj,cname) {
		if (this.hasClass(obj,cname)) obj.className=obj.className.replace(new RegExp('(\\s|^)'+cname+'(\\s|$)'),' ');
	},
	getAllClasses: function(cname, prefix, skip) {
		if(!skip) skip = '';
		if(!prefix) prefix = '';
		return cname ? cname.replace(new RegExp('(\\s|^)'+skip+'(\\s|$)'),' ').replace(/[\s]*([\S]+)+[\s]*/gi,prefix+"$1 ") : '';
	},
	getElementsBySelector: function(selector, scope) {
		// Attempt to fail gracefully in lesser browsers
		if (!document.getElementsByTagName) {
			return new Array();
		}
		// Split selector in to tokens
		var tokens = selector.split(' ');
		var currentContext = new Array(scope || document.body);
		for (var i = 0; i < tokens.length; i++) {
			token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');
			if (token.indexOf('#') > -1) {
				// Token is an ID selector
				var bits = token.split('#');
				var tagName = bits[0];
				var id = bits[1];
				var element = document.getElementById(id);
				if (tagName && element.nodeName.toLowerCase() != tagName) {
					// tag with that ID not found, return false
					return new Array();
				}
				// Set currentContext to contain just this element
				currentContext = new Array(element);
				continue; // Skip to next token
			}
			if (token.indexOf('.') > -1) {
				// Token contains a class selector
				var bits = token.split('.');
				var tagName = bits[0];
				var className = bits[1];
				if (!tagName) {
					tagName = '*';
				}
				// Get elements matching tag, filter them for class selector
				var found = new Array;
				var foundCount = 0;
				for (var h = 0; h < currentContext.length; h++) {
					var elements;
					if (tagName == '*') {
						elements = currentContext[h].getElementsByTagName('*');
					} else {
						elements = currentContext[h].getElementsByTagName(tagName);
					}
					for (var j = 0; j < elements.length; j++) {
						found[foundCount++] = elements[j];
					}
				}
				currentContext = new Array;
				var currentContextIndex = 0;
				for (var k = 0; k < found.length; k++) {
					if (found[k].className && found[k].className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'))) {
						currentContext[currentContextIndex++] = found[k];
					}
				}
				continue; // Skip to next token
			}
			// Code to deal with attribute selectors
			if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
				var tagName = RegExp.$1;
				var attrName = RegExp.$2;
				var attrOperator = RegExp.$3;
				var attrValue = RegExp.$4;
				if (!tagName) {
					tagName = '*';
				}
				// Grab all of the tagName elements within current context
				var found = new Array;
				var foundCount = 0;
				for (var h = 0; h < currentContext.length; h++) {
					var elements;
					if (tagName == '*') {
						elements = currentContext[h].getElementsByTagName('*');
					} else {
						elements = currentContext[h].getElementsByTagName(tagName);
					}
					for (var j = 0; j < elements.length; j++) {
						found[foundCount++] = elements[j];
					}
				}
				currentContext = new Array;
				var currentContextIndex = 0;
				var checkFunction; // This function will be used to filter the elements
				if(attrName.toLowerCase() == 'for' && jcf.lib.browser.msie && jcf.lib.browser.version < 8) {
					attrName = 'htmlFor';
				}
				switch (attrOperator) {
					case '=': // Equality
						checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
						break;
					case '~': // Match one of space seperated words
						checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('(\\s|^)'+attrValue+'(\\s|$)'))); };
						break;
					case '|': // Match start with value followed by optional hyphen
						checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
						break;
					case '^': // Match starts with value
						checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
						break;
					case '$': // Match ends with value
						checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
						break;
					case '*': // Match ends with value
						checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
						break;
					default :
						// Just test for existence of attribute
						checkFunction = function(e) { return e.getAttribute(attrName); };
				}
				currentContext = new Array;
				var currentContextIndex = 0;
				for (var k = 0; k < found.length; k++) {
					if (checkFunction(found[k])) {
						currentContext[currentContextIndex++] = found[k];
					}
				}
				continue; // Skip to next token
			}
			// If we get here, token is JUST an element (not a class or ID selector)
			tagName = token;
			var found = new Array;
			var foundCount = 0;
			for (var h = 0; h < currentContext.length; h++) {
				var elements = currentContext[h].getElementsByTagName(tagName);
				for (var j = 0; j < elements.length; j++) {
					found[foundCount++] = elements[j];
				}
			}
			currentContext = found;
		}
		return currentContext;
	},
	domReady: function (handler){
		var called = false
		function ready() {
			if (called) return;
			called = true;
			handler();
		}
		if (document.addEventListener) {
			document.addEventListener( "DOMContentLoaded", ready, false )
		} else if (document.attachEvent) {
			if (document.documentElement.doScroll && window == window.top) {
				function tryScroll(){
					if (called) return
					if (!document.body) return
					try {
						document.documentElement.doScroll("left")
						ready()
					} catch(e) {
						setTimeout(tryScroll, 0)
					}
				}
				tryScroll()
			}
			document.attachEvent("onreadystatechange", function(){
				if ( document.readyState === "complete" ) {
					ready()
				}
			})
		}
		if (window.addEventListener) window.addEventListener('load', ready, false)
		else if (window.attachEvent) window.attachEvent('onload', ready)
	},
	event: (function(){
		var guid = 0;
		function fixEvent(event) {
			event = event || window.event;
			if ( event.isFixed ) {
				return event;
			}
			event.isFixed = true;
			event.preventDefault = event.preventDefault || function(){this.returnValue = false}
			event.stopPropagation = event.stopPropagaton || function(){this.cancelBubble = true}
			if(!event.target) {
				event.target = event.srcElement;
			}
			if(!event.relatedTarget && event.fromElement) {
				event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
			}
			if(event.pageX == null && event.clientX != null ) {
				var html = document.documentElement, body = document.body;
				event.pageX = event.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0);
				event.pageY = event.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0);
			}
			if(typeof event.layerX == 'undefined') {
				event.layerX = event.offsetX;
				event.layerY = event.offsetY;
			}
			if(!event.which && event.button ) {
				event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
			}
			return event;
		}

		function commonHandle(event) {
			if(!this.events) return;
			event = fixEvent(event)
			var handlers = this.events[event.type]
			for(var g in handlers ) {
				var handler = handlers[g]
				var ret = handler.call(this, event)
				if ( ret === false ) {
					event.preventDefault()
					event.stopPropagation()
				}
			}
		}

		return {
			add: function(elem, type, handler) {
				if (elem.setInterval && (elem != window && !elem.frameElement)) {
					elem = window;
				}
				if (!handler.guid) {
					handler.guid = ++guid;
				}
				if (!elem.events) {
					elem.events = {}
					elem.handle = function(event) {
						if (typeof jcf.lib.event !== "undefined") {
							return commonHandle.call(elem, event)
						}
					}
				}

				if (!elem.events[type]) {
					elem.events[type] = {}
					if (elem.addEventListener) {
						elem.addEventListener(type, elem.handle, true);
					} else {
						if (elem.attachEvent) elem.attachEvent('on' + type, elem.handle);
					}
				}
				elem.events[type][handler.guid] = handler
			},

			remove: function(elem, type, handler) {
				var handlers = elem.events && elem.events[type];
				if (!handlers) return;
				delete handlers[handler.guid];
				for(var any in handlers) return;
				if (elem.removeEventListener) elem.removeEventListener(type, elem.handle, false)
				else if (elem.detachEvent) elem.detachEvent("on" + type, elem.handle)
				delete elem.events[type]

				for (var any in elem.events) return;
				try {
					delete elem.handle
					delete elem.events
				} catch(e) { // IE
					try {
						elem.removeAttribute("handle")
						elem.removeAttribute("events")
					} catch(e) {}
				}
			}
		}
	}())
}

// custom scrollbars module
jcf.addModule({
	name:'customscroll',
	selector:'div.scrollable-area',
	initOptions: function(){
		jcf.lib.extend(this.options,{
			scrollSensitivity: 6,
			scrollDistance: 125,
			scrollInterval: 10,
			focusClass:'scrollable-focus',
			innerWrapperClass:'scrollable-inner-wrapper',
			scrollWrapperClass:'scrollable-area-wrapper',
			horizontalClass: 'hscrollable',
			verticalClass: 'vscrollable',
			bothClass: 'anyscrollable',
			vScrollBarClass:'vscrollbar',
			vScrollStructure: '<div class="vscroll-up"></div><div class="vscroll-down"></div><div class="vscroll-line"></div><div class="vscroll-slider"><div class="scroll-bar-top"></div><div class="scroll-bar-bottom"></div></div></div>',
			vScrollBtnUpClass:'div.vscroll-up',
			vScrollBtnDownClass:'div.vscroll-down',
			vScrollSliderClass:'div.vscroll-slider',
			hScrollBarClass:'hscrollbar',
			hScrollStructure: '<div class="hscroll-left"></div><div class="hscroll-right"></div><div class="hscroll-line"></div><div class="hscroll-slider"><div class="scroll-bar-left"></div><div class="scroll-bar-right"></div></div></div>',
			hScrollBtnLeftClass:'div.hscroll-left',
			hScrollBtnRightClass:'div.hscroll-right',
			hScrollSliderClass:'div.hscroll-slider'
		});
	},
	replaceObject: function(){
		this.initStructure();
		this.refreshState();
		this.addEvents();
	},
	initStructure: function(){
		// set type of scroll
		this.realElement.setAttribute('tabindex',0);
		if(jcf.lib.hasClass(this.realElement, this.options.bothClass)) {
			this.scrollType = 'both';
		} else {
			if(jcf.lib.hasClass(this.realElement, this.options.horizontalClass) && jcf.lib.hasClass(this.realElement, this.options.verticalClass)) {
				this.scrollType = 'both';
			} else {
				if(jcf.lib.hasClass(this.realElement, this.options.horizontalClass)) {
					this.scrollType = 'horizontal';
				} else {
					this.scrollType = 'vertical';
				}
			}
		}

		// build structure for scrollable area
		this.origDimensions = {
			scrollWidth:this.realElement.scrollWidth,
			scrollHeight:this.realElement.scrollHeight,
			scrollTop:this.realElement.scrollTop,
			scrollLeft:this.realElement.scrollLeft,
			width:this.realElement.offsetWidth,
			height:this.realElement.offsetHeight
		}

		this.realElement.jcf = this;
		this.realElement.style.width = this.origDimensions.width+'px';
		this.realElement.style.height = this.origDimensions.height+'px';
		this.realElement.style.position = 'relative'
		this.realElement.style.overflow = 'hidden'

		this.buildWrapper();
		if(this.scrollType == 'horizontal' || this.scrollType == 'both') {
			this.buildHorizontalScrollbar();
		}
		if(this.scrollType == 'vertical' || this.scrollType == 'both'){
			this.buildVerticalScrollbar();
		}

		// get elements
		if(this.vScrollBar) {
			this.btnUp = jcf.lib.queryBySelector(this.options.vScrollBtnUpClass,this.vScrollBar)[0];
			this.btnDown = jcf.lib.queryBySelector(this.options.vScrollBtnDownClass,this.vScrollBar)[0];
			this.vSlider = jcf.lib.queryBySelector(this.options.vScrollSliderClass,this.vScrollBar)[0];
			this.btnUp.jcf = this;
			this.btnDown.jcf = this;
			this.vSlider.jcf = this;
		}
		if(this.hScrollBar) {
			this.btnLeft = jcf.lib.queryBySelector(this.options.hScrollBtnLeftClass,this.hScrollBar)[0];
			this.btnRight = jcf.lib.queryBySelector(this.options.hScrollBtnRightClass,this.hScrollBar)[0];
			this.hSlider = jcf.lib.queryBySelector(this.options.hScrollSliderClass,this.hScrollBar)[0];
			this.hSlider.jcf = this;
			this.btnLeft.jcf = this;
			this.btnRight.jcf = this;
		}

		// resize by scrollbar styles
		this.skipMargin = this.scrollType == 'both' ? this.vScrollBar.offsetWidth : 0;
		if(this.vScrollBar) {
			this.realElement.style.width = this.origDimensions.width - this.vScrollBar.offsetWidth + 'px';
			this.vScrollBar.style.height = this.origDimensions.height - this.skipMargin + 'px';
		}
		if(this.hScrollBar) {
			this.realElement.style.height = this.origDimensions.height - this.hScrollBar.offsetHeight + 'px';
			this.hScrollBar.style.width = this.origDimensions.width - this.skipMargin + 'px';
		}
		this.resizeControls();
	},
	buildWrapper: function(){
		// create wrapper
		this.scrollWrapper = document.createElement('div');
		this.scrollWrapper.className = this.options.scrollWrapperClass;
		this.scrollWrapper.style.width = this.realElement.style.width;
		this.scrollWrapper.style.height = this.realElement.style.height;
		this.scrollWrapper.style.overflow = 'hidden';
		this.realElement.parentNode.insertBefore(this.scrollWrapper, this.realElement);
		this.scrollWrapper.appendChild(this.realElement);

		// create scroll wrapper
		this.contentScroll = document.createElement('div');
		this.contentScroll.className = this.options.innerWrapperClass;
		this.contentScroll.style.overflow = 'hidden';
		this.contentScroll.style.width = this.origDimensions.scrollWidth + 'px';
		while(this.realElement.children.length) this.contentScroll.appendChild(this.realElement.children[0]);
		this.realElement.appendChild(this.contentScroll);
		this.realElement.scrollTop = this.origDimensions.scrollTop;
	},
	buildHorizontalScrollbar: function() {
		this.hScrollBar = document.createElement('div');
		this.hScrollBar.className = this.options.hScrollBarClass;
		this.hScrollBar.innerHTML = this.options.hScrollStructure;
		this.scrollWrapper.appendChild(this.hScrollBar);
		this.layX = 0;
	},
	buildVerticalScrollbar: function() {
		this.vScrollBar = document.createElement('div');
		this.vScrollBar.className = this.options.vScrollBarClass;
		this.vScrollBar.innerHTML = this.options.vScrollStructure;
		this.scrollWrapper.appendChild(this.vScrollBar);
		this.layY = 0;
	},
	recalcDimensions: function() {
		this.holderHeight = this.realElement.offsetHeight - this.skipMargin;
		this.holderWidth = this.realElement.offsetWidth - this.skipMargin;
		this.wrapperHeight = this.contentScroll.offsetHeight;
		this.wrapperWidth = this.contentScroll.offsetWidth;
	},
	resizeControls: function(e) {
		this.recalcDimensions();
		if(this.vScrollBar) {
			this.btnUpHeight = this.btnUp.offsetHeight;
			this.btnDownHeight = this.btnDown.offsetHeight;
			this.diffHeight = this.holderHeight - this.btnUpHeight - this.btnDownHeight + this.skipMargin;
			this.sliderHeight = Math.round((this.holderHeight * 100 / this.wrapperHeight) * this.diffHeight / 100);
			this.vSliderTop = this.vSliderTop || this.btnUpHeight;
			this.vSliderMaxTop = this.diffHeight + this.btnUpHeight - this.vSlider.offsetHeight;
			this.vSliderMinTop = this.btnUpHeight;
			if(e && e.layerY) this.layY = e.layerY;
			this.offsetTop = jcf.lib.getOffset(this.vScrollBar).top;
			this.minVerticalOffset = this.offsetTop + this.btnUpHeight;
			this.maxVerticalOffset = this.offsetTop + this.vSliderMaxTop;
		}
		if(this.hScrollBar) {
			this.btnLeftWidth = this.btnLeft.offsetWidth;
			this.btnRightWidth = this.btnRight.offsetWidth;
			this.diffWidth = this.holderWidth - this.btnLeftWidth - this.btnRightWidth + this.skipMargin;
			this.sliderWidth = Math.round((this.holderWidth * 100 / this.wrapperWidth) * this.diffWidth / 100);
			this.hSliderLeft = this.hSliderLeft || this.btnLeftWidth;
			this.hSliderMaxLeft = this.diffWidth + this.btnLeftWidth - this.hSlider.offsetWidth;
			this.hSliderMinLeft = this.btnLeftWidth;
			if(e && e.layerX) this.layX = e.layerX;
			this.offsetLeft = jcf.lib.getOffset(this.hScrollBar).left;
			this.minHorizontalOffset = this.offsetLeft + this.btnLeftWidth;
			this.maxHorizontalOffset = this.offsetLeft + this.hSliderMaxLeft;
		}
	},
	refreshState: function(posOnly) {
		if(this.vScrollBar) {
			this.vSlider.style.top = this.vSliderTop + 'px';
			this.vSlider.style.height = this.sliderHeight + 'px';
			if(!posOnly) this.realElement.scrollTop = this.offsetToScrollTop(parseInt(this.vSlider.style.top) - this.btnUpHeight);
		}
		if(this.hScrollBar) {
			this.hSlider.style.left = this.hSliderLeft + 'px';
			this.hSlider.style.width = this.sliderWidth + 'px';
			if(!posOnly) this.realElement.scrollLeft = this.offsetToScrollLeft(parseInt(this.hSlider.style.left) - this.btnLeftWidth);
		}
	},
	offsetToScrollLeft: function(c) {
		this.scrollPercent = c * 100 / (this.diffWidth - this.hSlider.offsetWidth);
		return (this.scrollPercent * (this.wrapperWidth - this.holderWidth)) / 100;
	},
	offsetToScrollTop: function(c) {
		this.scrollPercent = c * 100 / (this.diffHeight - this.vSlider.offsetHeight);
		return (this.scrollPercent * (this.wrapperHeight - this.holderHeight)) / 100;
	},
	scrollTopToOffset: function(c) {
		this.scrollPercent = c * 100 / (this.wrapperHeight - this.holderHeight);
		return this.scrollPercent * (this.diffHeight - this.vSlider.offsetHeight) / 100;
	},
	scrollLeftToOffset: function(c) {
		this.scrollPercent = c * 100 / (this.wrapperWidth - this.holderWidth);
		return this.scrollPercent * (this.diffWidth - this.hSlider.offsetWidth) / 100;
	},
	scrollUp: function() {
		clearInterval(jcf.actScroll.scrollTimer);
		if(jcf.actScroll.realElement.scrollTop - jcf.actScroll.options.scrollSensitivity > 0) {
			jcf.actScroll.realElement.scrollTop -= jcf.actScroll.options.scrollSensitivity;
			jcf.actScroll.vSliderTop = jcf.actScroll.scrollTopToOffset(jcf.actScroll.realElement.scrollTop) + jcf.actScroll.btnUpHeight;
			jcf.actScroll.refreshState(true);
			jcf.actScroll.scrollTimer = setInterval(jcf.actScroll.scrollUp, jcf.actScroll.options.scrollInterval);
		} else {
			jcf.actScroll.vSliderTop = jcf.actScroll.btnUpHeight;
			jcf.actScroll.refreshState();
		}
	},
	scrollDown: function() {
		clearInterval(jcf.actScroll.scrollTimer);
		if(jcf.actScroll.realElement.scrollTop + jcf.actScroll.options.scrollSensitivity < jcf.actScroll.wrapperHeight) {
			jcf.actScroll.realElement.scrollTop += jcf.actScroll.options.scrollSensitivity;
			jcf.actScroll.vSliderTop = jcf.actScroll.scrollTopToOffset(jcf.actScroll.realElement.scrollTop) + jcf.actScroll.btnUpHeight;
			jcf.actScroll.refreshState(true);
			jcf.actScroll.scrollTimer = setInterval(jcf.actScroll.scrollDown, jcf.actScroll.options.scrollInterval);
		} else {
			jcf.actScroll.vSliderTop = jcf.actScroll.vSliderMaxTop;
			jcf.actScroll.refreshState();
		}
	},
	scrollLeft: function() {
		clearInterval(jcf.actScroll.scrollTimer);
		if(jcf.actScroll.realElement.scrollLeft - jcf.actScroll.options.scrollSensitivity > 0) {
			jcf.actScroll.realElement.scrollLeft -= jcf.actScroll.options.scrollSensitivity;
			jcf.actScroll.hSliderLeft = jcf.actScroll.scrollLeftToOffset(jcf.actScroll.realElement.scrollLeft) + jcf.actScroll.btnLeftWidth;
			jcf.actScroll.refreshState(true);
			jcf.actScroll.scrollTimer = setInterval(jcf.actScroll.scrollLeft, jcf.actScroll.options.scrollInterval);
		} else {
			jcf.actScroll.hSliderLeft = jcf.actScroll.btnLeftWidth;
			jcf.actScroll.refreshState();
		}
	},
	scrollRight: function() {
		clearInterval(jcf.actScroll.scrollTimer);
		if(jcf.actScroll.realElement.scrollLeft + jcf.actScroll.options.scrollSensitivity < jcf.actScroll.wrapperWidth) {
			jcf.actScroll.realElement.scrollLeft += jcf.actScroll.options.scrollSensitivity;
			jcf.actScroll.hSliderLeft = jcf.actScroll.scrollLeftToOffset(jcf.actScroll.realElement.scrollLeft) + jcf.actScroll.btnLeftWidth;
			jcf.actScroll.refreshState(true);
			jcf.actScroll.scrollTimer = setInterval(jcf.actScroll.scrollRight, jcf.actScroll.options.scrollInterval);
		} else {
			jcf.actScroll.hSliderLeft = jcf.actScroll.hSliderMaxLeft;
			jcf.actScroll.refreshState();
		}
	},
	scrollUpBy: function(px) {
		jcf.actScroll.stopScroll();
		jcf.actScroll.destTop = jcf.actScroll.realElement.scrollTop - px > 0 ? jcf.actScroll.realElement.scrollTop - px : 0;
		jcf.actScroll.scrollByTimer = setInterval(function(){
			if(jcf.actScroll.realElement.scrollTop <= jcf.actScroll.destTop) {
				jcf.actScroll.stopScroll();
			} else {
				jcf.actScroll.scrollUp();
			}
		},jcf.actScroll.options.scrollInterval);
	},
	scrollDownBy: function(px) {
		jcf.actScroll.stopScroll();
		jcf.actScroll.destTop = jcf.actScroll.realElement.scrollTop + px < jcf.actScroll.wrapperHeight - jcf.actScroll.holderHeight ? jcf.actScroll.realElement.scrollTop + px : jcf.actScroll.wrapperHeight - jcf.actScroll.holderHeight;
		jcf.actScroll.scrollByTimer = setInterval(function(){
			if(jcf.actScroll.realElement.scrollTop >= jcf.actScroll.destTop) {
				jcf.actScroll.stopScroll();
			} else {
				jcf.actScroll.scrollDown();
			}
		},jcf.actScroll.options.scrollInterval);
	},
	stopScroll: function() {
		clearInterval(jcf.actScroll.scrollTimer);
		clearInterval(jcf.actScroll.scrollByTimer);
	},
	scrollTo: function(x,y) {
		x = x || jcf.actScroll.realElement.scrollLeft;
		y = y || jcf.actScroll.realElement.scrollTop;
		jcf.actScroll.vSliderTop = jcf.actScroll.scrollTopToOffset(y) + jcf.actScroll.btnUpHeight;
		jcf.actScroll.refreshState(true);
	},
	scrollAtTop: function() {
		if(this.vSliderTop == this.vSliderMinTop) {
			return true;
		}
		return false;
	},
	scrollAtBottom: function() {
		if(this.vSliderTop == this.vSliderMaxTop) {
			return true;
		}
		return false;
	},
	addEvents: function(){
		// vertical scrollbar
		if(this.vScrollBar) {
			jcf.lib.event.add(this.vSlider, 'mousedown', this.onVerticalMouseDown);
			jcf.lib.event.add(this.btnDown, 'mousedown', this.onBtnDownPress);
			jcf.lib.event.add(this.btnDown, 'mouseup', this.onBtnDownRelease);
			jcf.lib.event.add(this.btnUp, 'mousedown', this.onBtnUpPress);
			jcf.lib.event.add(this.btnUp, 'mouseup', this.onBtnUpRelease);
		}
		// horizontal scrollbar
		if(this.hScrollBar) {
			jcf.lib.event.add(this.hSlider, 'mousedown', this.onHorizontalMouseDown);
			jcf.lib.event.add(this.btnRight, 'mousedown', this.onBtnRightPress);
			jcf.lib.event.add(this.btnRight, 'mouseup', this.onBtnRightRelease);
			jcf.lib.event.add(this.btnLeft, 'mousedown', this.onBtnLeftPress);
			jcf.lib.event.add(this.btnLeft, 'mouseup', this.onBtnLeftRelease);
		}

		// wheel events
		jcf.lib.event.add(this.realElement, 'DOMMouseScroll', this.onMouseWheel);
		jcf.lib.event.add(this.realElement, 'mousewheel', this.onMouseWheel);
		jcf.lib.event.add(this.realElement, 'focus', this.onFocus);
		jcf.lib.event.add(this.realElement, 'blur', this.onBlur);
	},
	onFocus: function(){
		jcf.lib.addClass(this.jcf.scrollWrapper,this.jcf.options.focusClass);
	},
	onBlur: function(){
		jcf.lib.removeClass(this.jcf.scrollWrapper,this.jcf.options.focusClass);
	},
	onBtnUpPress: function() {
		jcf.actScroll = this.jcf;
		jcf.actScroll.resizeControls();
		jcf.actScroll.scrollUp();
	},
	onBtnUpRelease: function() {
		jcf.actScroll = this.jcf;
		jcf.actScroll.stopScroll();
	},
	onBtnDownPress: function() {
		jcf.actScroll = this.jcf;
		jcf.actScroll.resizeControls();
		jcf.actScroll.scrollDown();
	},
	onBtnDownRelease: function() {
		jcf.actScroll = this.jcf;
		jcf.actScroll.stopScroll();
	},
	onBtnLeftPress: function() {
		jcf.actScroll = this.jcf;
		jcf.actScroll.resizeControls();
		jcf.actScroll.scrollLeft();
	},
	onBtnLeftRelease: function() {
		jcf.actScroll = this.jcf;
		jcf.actScroll.stopScroll();
	},
	onBtnRightPress: function() {
		jcf.actScroll = this.jcf;
		jcf.actScroll.resizeControls();
		jcf.actScroll.scrollRight();
	},
	onBtnRightRelease: function() {
		jcf.actScroll = this.jcf;
		jcf.actScroll.stopScroll();
	},
	onMouseWheel: function(e) {
		// detect wheel direction
		var delta = 0;
		if (e.wheelDelta) {
			delta = e.wheelDelta/120;
		} else if (e.detail) {
			delta = -e.detail/3;
		}

		// nested scrollbars check
		var curTarget = e.target;
		var scrollTarget = this.jcf;
		do {
			if(curTarget.jcf && curTarget.jcf.name == 'customscroll') {
				scrollTarget = curTarget;
				break;
			}
			curTarget = curTarget.parentNode;
		} while(curTarget.parentNode);

		// perform scroll
		if(jcf.actScroll) {
			jcf.actScroll.stopScroll();
		}
		if(delta < 0) {
			if(!scrollTarget.jcf.scrollAtBottom()) {
				jcf.actScroll = scrollTarget.jcf;
				jcf.actScroll.resizeControls();
				jcf.actScroll.scrollDownBy(jcf.actScroll.options.scrollDistance);
				return false;
			}
		} else {
			if(!scrollTarget.jcf.scrollAtTop()) {
				jcf.actScroll = scrollTarget.jcf;
				jcf.actScroll.resizeControls();
				jcf.actScroll.scrollUpBy(jcf.actScroll.options.scrollDistance);
				return false;
			}
		}
	},
	onVerticalMouseDown: function(e){
		jcf.actScroll = this.jcf;
		jcf.actScroll.resizeControls(e);
		jcf.lib.event.add(document.body, 'mouseup', jcf.actScroll.onVerticalMouseUp);
		jcf.lib.event.add(document.body, 'mousemove', jcf.actScroll.onVerticalMouseMove);
		jcf.lib.disableSelection(); // IE
		return false; // W3C
	},
	onVerticalMouseMove: function(e){
		if(jcf.actScroll) {
			if(e.pageY - jcf.actScroll.layY > jcf.actScroll.minVerticalOffset) {
				if(e.pageY - jcf.actScroll.layY < jcf.actScroll.maxVerticalOffset) {
					jcf.actScroll.vSliderTop = e.pageY - jcf.actScroll.layY - jcf.actScroll.offsetTop;
				} else {
					jcf.actScroll.vSliderTop = jcf.actScroll.maxVerticalOffset - jcf.actScroll.offsetTop;
				}
			} else {
				jcf.actScroll.vSliderTop = jcf.actScroll.btnUpHeight;
			}
			jcf.actScroll.refreshState();
		}
	},
	onVerticalMouseUp: function(){
		jcf.lib.event.remove(document.body, 'mouseup', jcf.actScroll.onVerticalMouseUp);
		jcf.lib.event.remove(document.body, 'mousemove', jcf.actScroll.onVerticalMouseMove);
		jcf.lib.enableSelection(); // IE
	},
	onHorizontalMouseDown: function(e){
		jcf.actScroll = this.jcf;
		jcf.actScroll.resizeControls(e);
		jcf.lib.event.add(document.body, 'mouseup', jcf.actScroll.onHorizontalMouseUp);
		jcf.lib.event.add(document.body, 'mousemove', jcf.actScroll.onHorizontalMouseMove);
		jcf.lib.disableSelection(); // IE
		return false; // W3C
	},
	onHorizontalMouseMove: function(e){
		if(jcf.actScroll) {
			if(e.pageX - jcf.actScroll.layX > jcf.actScroll.minHorizontalOffset) {
				if(e.pageX - jcf.actScroll.layX < jcf.actScroll.maxHorizontalOffset) {
					jcf.actScroll.hSliderLeft = e.pageX - jcf.actScroll.layX - jcf.actScroll.offsetLeft;
				} else {
					jcf.actScroll.hSliderLeft = jcf.actScroll.maxHorizontalOffset - jcf.actScroll.offsetLeft;
				}
			} else {
				jcf.actScroll.hSliderLeft = jcf.actScroll.btnLeftWidth;
			}
			jcf.actScroll.refreshState();
		}
	},
	onHorizontalMouseUp: function(){
		jcf.lib.event.remove(document.body, 'mouseup', jcf.actScroll.onHorizontalMouseUp);
		jcf.lib.event.remove(document.body, 'mousemove', jcf.actScroll.onHorizontalMouseMove);
		jcf.lib.enableSelection(); // IE
	},
	onCreateModule: function(){
		if(jcf.modules.select) {
			this.extendSelect();
		}
	},
	onModuleAdded: function(module){
		if(module.prototype.name == 'select') {
			this.extendSelect();
		}
	},
	extendSelect: function() {
		// add scrollable if needed on control ready
		jcf.modules.select.prototype.onControlReady = function(obj){
			if(obj.selectDrop.offsetHeight > obj.options.dropMaxHeight) {
				obj.jcfScrollable = new jcf.modules.customscroll({
					replaces:obj.selectList
				});
			}
		}

		// update scroll function
		var orig = jcf.modules.select.prototype.scrollToItem;
		jcf.modules.select.prototype.scrollToItem = function(){
			orig.apply(this);
			if(this.jcfScrollable) {
				jcf.actScroll = this.jcfScrollable;
				jcf.actScroll.scrollTo();
			}
		}
	}
});

// custom select module
jcf.addModule({
    name: 'select',
    selector: 'select',
    initOptions: function () {
        jcf.lib.extend(this.options, {
            wrapperClass: 'selectArea',
            focusClass: 'select-focus',
            selectedClass: 'item-selected',
            disabledClass: 'select-disabled',
            valueSelector: 'span.center',
            optGroupClass: 'optgroup',
            openerSelector: 'a.selectButton',
            selectStructure: '<span class="left"></span><span class="center"></span><a class="selectButton"></a>',
            selectPrefixClass: '',
            dropMaxHeight: 172,
            dropHiddenClass: 'optionsDivInvisible',
            dropScrollableClass: 'options-overflow',
            dropClass: 'optionsDivVisible',
            dropClassPrefix: 'drop-',
            dropStructure: '<div class="select-top"></div><div class="drop-holder"><div class="drop-list"></div></div><div class="select-bottom"></div>',
            dropSelector: 'div.drop-list'
        });
    },
    setupWrapper: function () {
        jcf.lib.addClass(this.fakeElement, this.options.wrapperClass);
        this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement);
        if (!jcf.lib.browser.opera) this.realElement.setAttribute('multiple', 'multiple'); // Mac Safari Fix
        this.fakeElement.innerHTML = this.options.selectStructure;
        this.fakeElement.style.width = this.realElement.offsetWidth + 'px';
        jcf.lib.addClass(this.fakeElement, jcf.lib.getAllClasses(this.realElement.className, this.options.selectPrefixClass, jcf.baseOptions.hiddenClass));

        // create select body
        this.opener = jcf.lib.queryBySelector(this.options.openerSelector, this.fakeElement)[0];
        this.valueText = jcf.lib.queryBySelector(this.options.valueSelector, this.fakeElement)[0];
        this.opener.jcf = this;

        this.createDropdown();
        this.refreshState();
        this.addEvents();
        this.onControlReady(this);
    },
    addEvents: function () {
        jcf.lib.event.add(this.fakeElement, 'click', this.toggleDropdown);
        jcf.lib.event.add(this.realElement, 'change', this.onChange);
    },
    onFocus: function () {
        jcf.modules[this.jcf.name].superclass.onFocus.apply(this, arguments);
        jcf.lib.event.add(this.jcf.realElement, 'keydown', this.jcf.onKeyDown);
        if (jcf.activeControl && jcf.activeControl != this.jcf) {
            jcf.activeControl.hideDropdown();
        }
    },
    onBlur: function () {
        if (!this.jcf.isActiveDrop() || !this.jcf.isOverDrop()) {
            jcf.modules[this.jcf.name].superclass.onBlur.apply(this, arguments);
        }
        jcf.lib.event.remove(this.jcf.realElement, 'keydown', this.jcf.onKeyDown);
    },
    onChange: function () {
        this.jcf.refreshState();
    },
    onKeyDown: function (e) {
        var context = this;
        context.jcf.keyboardFix = true;
        setTimeout(function () {
            context.jcf.refreshState();
        }, 10);
        if (e.keyCode == 13) {
            context.jcf.toggleDropdown.apply(context);
            return false;
        }
    },
    onResizeWindow: function (e) {
        if (jcf.activeControl) {
            jcf.activeControl.hideDropdown();
        }
    },
    onScrollWindow: function (e) {
        if (jcf.activeControl) {
            jcf.activeControl.positionDropdown();
        }
    },
    onOptionClick: function (e) {
        var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li');
        if (opener) {
            this.jcf.realElement.selectedIndex = parseInt(opener.getAttribute('rel'));
            this.jcf.realElement.focus();
            this.jcf.refreshState();
            this.jcf.hideDropdown();
            jcf.lib.fireEvent(this.jcf.realElement, 'change');
        }
        return false;
    },
    onClickOutside: function (e) {
        if (jcf.activeControl && !jcf.lib.isParent(jcf.activeControl, e.target) && !jcf.lib.isParent(jcf.activeControl.fakeElement, e.target)) {
            if (!jcf.lib.isParent(jcf.activeControl.selectDrop, e.target)) {
                jcf.activeControl.hideDropdown();
            }
        }
    },
    onDropHover: function (e) {
        if (jcf.activeControl && !jcf.activeControl.keyboardFix) {
            jcf.activeControl.hoverFlag = true;
            var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li');
            if (opener) {
                jcf.activeControl.realElement.selectedIndex = parseInt(opener.getAttribute('rel'));
                jcf.activeControl.refreshSelectedClass(parseInt(opener.getAttribute('rel')));
            }
        } else {
            if (jcf.activeControl) {
                jcf.activeControl.keyboardFix = false;
            }
        }
    },
    onDropLeave: function () {
        if (jcf.activeControl) {
            jcf.activeControl.hoverFlag = false;
        }
    },
    isActiveDrop: function () {
        return !jcf.lib.hasClass(this.selectDrop, this.options.dropHiddenClass);
    },
    isOverDrop: function () {
        return this.hoverFlag;
    },
    createDropdown: function () {
        // remove old dropdown if exists
        if (this.selectDrop) {
            this.selectDrop.parentNode.removeChild(this.selectDrop);
        }

        // create dropdown holder
        this.selectDrop = document.createElement('div');
        this.selectDrop.className = this.options.dropClass;
        this.selectDrop.innerHTML = this.options.dropStructure;
        this.selectList = jcf.lib.queryBySelector(this.options.dropSelector, this.selectDrop)[0];
        jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass);
        document.body.appendChild(this.selectDrop);
        this.selectDrop.jcf = this;
        jcf.lib.event.add(this.selectDrop, 'click', this.onOptionClick);
        jcf.lib.event.add(this.selectDrop, 'mouseover', this.onDropHover);
        jcf.lib.event.add(this.selectDrop, 'mouseout', this.onDropLeave);
        this.buildDropdown();
    },
    buildDropdown: function () {
        // build select options / optgroups
        this.buildDropdownOptions();

        // position and resize dropdown
        this.positionDropdown();

        // cut dropdown if height exceedes
        this.buildDropdownScroll();
    },
    buildDropdownOptions: function () {
        this.resStructure = '';
        this.optNum = 0;
        for (var i = 0; i < this.realElement.children.length; i++) {
            this.resStructure += this.buildElement(this.realElement.children[i]) + '\n';
        }
        this.selectList.innerHTML = this.resStructure;
    },
    buildDropdownScroll: function () {
        if (this.options.dropMaxHeight) {
            if (this.selectDrop.offsetHeight > this.options.dropMaxHeight) {
                this.selectList.style.height = this.options.dropMaxHeight + 'px';
                this.selectList.style.overflow = 'auto';
                this.selectList.style.overflowX = 'hidden';
                jcf.lib.addClass(this.selectDrop, this.options.dropScrollableClass);
            }
        }
        jcf.lib.addClass(this.selectDrop, jcf.lib.getAllClasses(this.realElement.className, this.options.dropClassPrefix, jcf.baseOptions.hiddenClass));
    },
    buildElement: function (obj) {
        // build option
        var res = '';
        if (obj.tagName.toLowerCase() == 'option') {
            if (!jcf.lib.prevSibling(obj) || jcf.lib.prevSibling(obj).tagName.toLowerCase() != 'option') {
                res += '<ul>';
            }
            res += '<li rel="' + (this.optNum++) + '" class="' + (obj.className ? obj.className : '') + ' jcfcalc"><a href="#">' + (obj.title ? "<span class='smallIcons si_" + obj.title.toLowerCase() + "'></span>" : '') + '<span>' + obj.innerHTML + '</span></a></li>';
            if (!jcf.lib.nextSibling(obj) || jcf.lib.nextSibling(obj).tagName.toLowerCase() != 'option') {
                res += '</ul>';
            }
            return res;
        }
        // build option group with options
        else if (obj.tagName.toLowerCase() == 'optgroup' && obj.label) {
            res += '<div class="' + this.options.optGroupClass + '">';
            res += '<strong class="jcfcalc"><em>' + (obj.label) + '</em></strong>';
            for (var i = 0; i < obj.children.length; i++) {
                res += this.buildElement(obj.children[i]);
            }
            res += '</div>';
            return res;
        }
    },
    positionDropdown: function () {
        var ofs = jcf.lib.getOffset(this.fakeElement);
        this.selectDrop.style.top = (ofs.top + this.fakeElement.offsetHeight) + 'px';
        this.selectDrop.style.left = ofs.left + 'px';
        this.selectDrop.style.width = this.fakeElement.offsetWidth + 'px';
    },
    showDropdown: function () {
        jcf.lib.removeClass(this.selectDrop, this.options.dropHiddenClass);
        this.positionDropdown();

        // hide active dropdown
        if (jcf.activeControl) {
            jcf.activeControl.hideDropdown();
        }

        // show current dropdown
        jcf.activeControl = this;
        jcf.lib.event.add(window, 'resize', this.onResizeWindow);
        jcf.lib.event.add(window, 'scroll', this.onScrollWindow);
        jcf.lib.event.add(document.body, 'click', this.onClickOutside);
        this.positionDropdown();
    },
    hideDropdown: function () {
        if (jcf.activeControl && typeof jcf.activeControl.origSelectedIndex === 'number') {
            jcf.activeControl.realElement.selectedIndex = jcf.activeControl.origSelectedIndex;
        }
        jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass);
        jcf.activeControl = null;
        jcf.lib.event.remove(window, 'resize', this.onResizeWindow);
        jcf.lib.event.remove(window, 'scroll', this.onScrollWindow);
        jcf.lib.event.remove(document.body, 'click', this.onClickOutside);
    },
    toggleDropdown: function () {
        if ($(this).hasClass('disabled'))
            return;

        this.jcf.dropOpened = true;
        if (!this.jcf.realElement.disabled) {
            if (this.jcf.isActiveDrop()) {
                this.jcf.hideDropdown();
            } else {
                this.jcf.showDropdown();
            }
        }
        this.jcf.refreshState();
    },
    scrollToItem: function () {
        if (this.isActiveDrop()) {
            var dropHeight = this.selectList.offsetHeight;
            var offsetTop = this.calcOptionOffset(this.getFakeActiveOption());
            var sTop = this.selectList.scrollTop;
            var oHeight = this.getFakeActiveOption().offsetHeight;
            //offsetTop+=sTop;

            if (offsetTop >= sTop + dropHeight) {
                this.selectList.scrollTop = offsetTop - dropHeight + oHeight;
            } else if (offsetTop < sTop) {
                this.selectList.scrollTop = offsetTop;
            }
        }
    },
    getFakeActiveOption: function (c) {
        return jcf.lib.queryBySelector('li[rel="' + (typeof c === 'number' ? c : this.realElement.selectedIndex) + '"]', this.selectList)[0];
    },
    calcOptionOffset: function (fake) {
        var h = 0;
        var els = jcf.lib.queryBySelector('.jcfcalc', this.selectList);
        for (var i = 0; i < els.length; i++) {
            if (els[i] == fake) break;
            h += els[i].offsetHeight;
        }
        return h;
    },
    childrenHasItem: function (hold, item) {
        var items = hold.getElementsByTagName('*');
        for (i = 0; i < items.length; i++) {
            if (items[i] == item) return true;
        }
        return false;
    },
    removeSelectedClass: function () {
        var children = jcf.lib.queryBySelector('li', this.selectList);
        for (var i = children.length - 1; i >= 0; i--) {
            jcf.lib.removeClass(children[i], this.options.selectedClass);
        }
    },
    setSelectedClass: function (c) {
        jcf.lib.addClass(this.getFakeActiveOption(c), this.options.selectedClass);
    },
    refreshSelectedClass: function (c) {
        this.removeSelectedClass(c);
        this.setSelectedClass(c);
        if (this.realElement.disabled) {
            jcf.lib.addClass(this.fakeElement, this.options.disabledClass);
        } else {
            jcf.lib.removeClass(this.fakeElement, this.options.disabledClass);
        }
    },
    refreshSelectedText: function () {
        if (!this.dropOpened && this.realElement.title) {
            this.valueText.innerHTML = this.realElement.title;
        } else {
            if (this.realElement.options[this.realElement.selectedIndex].title) {
                this.valueText.innerHTML = "<span class='smallIcons si_" + this.realElement.options[this.realElement.selectedIndex].title.toLowerCase() + "'></span>" + this.realElement.options[this.realElement.selectedIndex].innerHTML;
            } else {
                this.valueText.innerHTML = this.realElement.options[this.realElement.selectedIndex].innerHTML;
            }
        }
    },
    refreshState: function () {
        if (jcf.activeControl) {
            jcf.activeControl.origSelectedIndex = jcf.activeControl.realElement.selectedIndex;
        }
        this.refreshSelectedClass();
        this.refreshSelectedText();
        this.scrollToItem();
    }
});

jcf.lib.domReady(function(){
	var cfManager = new jcf.customForms();
	cfManager.replace();
});
