;(function() {
	//main
	jQuery.fn.customForm = function(_options) {
		// defaults options

		var _options = jQuery.extend({
			replaceCheckbox: true,
			replaceRadios: false,
			replaceSelect: true,
			disableCustomClass: '.disable-customize',
			//select options
			selectHTML: '<div class="selectArea"><div class="left"></div><div class="center"></div><a href="#" class="selectButton">&nbsp;</a><div class="disabled"></div></div>',
			selectDisabled: '.disabled',
			selectText: '.center',
			selectBtn: '.selectButton',
			dropHTML: '<div class="drop-box"><div class="select-top"><div></div></div><div class="csbody"></div><div class="select-bottom"><div class="select-bottom-left"></div><div class="select-bottom-right"></div></div></div>',
			dropWidth: false,
			dropMaxHeight: false,
			markOptClass: 'marked',
			disableClass: 'disable_cs',
			onChangeFunc: null
		}, _options);

		return this.each(function() {
			var _this = this;
			//save options in each obj
			_this.opt = {};
			for (var key in _options) _this.opt[key] = _options[key];
			var _opt = _this.opt;
			//init replace checkbox
			if (_opt.replaceCheckbox) jQuery.fn.customForm.checkbox(_this, _opt);
			//init replace radiobox
			if (_opt.replaceRadios) jQuery.fn.customForm.radios(_this, _opt);
			//init replace selects
			if (_opt.replaceSelect) jQuery.fn.customForm.selects(_this, _opt);
		});
	};

	//get all radioboxs 
	jQuery.fn.customForm.radios = function(_this, _opt) {
		_this.radioAll = jQuery(_this).find('input:radio').not('.outtaHere').not(_opt.disableCustomClass);
		_this.radioAll.each(function() {
			var rBtn = this;
			//create
			if (this.checked) var initClass = 'radioAreaChecked';
			else var initClass = 'radioArea';
			rBtn._div = jQuery('<div class="' + initClass + ' ' + jQuery(this).attr('class') + '">');
			jQuery(this).before(rBtn._div);
			rBtn._label = jQuery('label[for=' + rBtn.id + ']');
			//disabled ? 
			if (rBtn.disabled) {
				rBtn._div.addClass('disabled');
				rBtn._label.addClass('disabled');
			};
			//events
			rBtn._update = function() {
				rBtn.name = jQuery(rBtn).attr('name');
				_this.radioAll.each(function() {
					if (jQuery(this).attr('name') == rBtn.name) {
						if (jQuery(this).is(':checked')) {
							this._div.removeClass('radioArea');
							this._div.addClass('radioAreaChecked');
						} else {
							this._div.addClass('radioArea');
							this._div.removeClass('radioAreaChecked');
						};
					};
				});
			};
			jQuery(rBtn).change(function() {
				rBtn._update();
			}).focus(function() {
				if (!rBtn._div.hasClass('cf-focus')) {
					rBtn._div.addClass('cf-focus');
				};
				rBtn._update();
			}).blur(function() {
				rBtn._div.removeClass('cf-focus checkedFocus');
				rBtn._update();
			});

			rBtn._div.mouseenter(function() {
				jQuery(this).addClass('hover');
				rBtn._label.addClass('hover');
			}).mouseleave(function() {
				jQuery(this).removeClass('hover');
				rBtn._label.removeClass('hover');
			}).click(function() {
				rBtn._div.addClass('cf-focus');
				jQuery(rBtn).focus();
				if (!jQuery(rBtn).is(':checked') && !rBtn.disabled) {
					rBtn.name = jQuery(rBtn).attr('name');
					rBtn.checked = true;
					_this.radioAll.each(function() {
						if (jQuery(this).attr('name') == rBtn.name) {
							if (jQuery(this).is(':checked')) {
								this._div.removeClass('radioArea');
								this._div.addClass('radioAreaChecked');
							} else {
								this._div.addClass('radioArea');
								this._div.removeClass('radioAreaChecked');
							};
						};
					});
					jQuery(this).removeClass('radioArea');
					jQuery(this).addClass('radioAreaChecked');
				};
			});
			//label events
			rBtn._label.mouseenter(function() {
				jQuery(this).addClass('hover');
				rBtn._div.addClass('hover');
			}).mouseleave(function() {
				jQuery(this).removeClass('hover');
				rBtn._div.removeClass('hover');
			}).click(function() {
				rBtn._div.trigger('click');
				return false;
			});
			jQuery(this).addClass('outtaHere');
		});
	};

	//get all checkboxs
	jQuery.fn.customForm.checkbox = function(_this, _opt) {
		_this.checkboxAll = jQuery(_this).find('input:checkbox').not('.outtaHere').not(_opt.disableCustomClass);
		_this.checkboxAll.each(function() {
			var cBtn = this;
			//create
			if (this.checked) var initClass = 'checkboxAreaChecked';
			else var initClass = 'checkboxArea';
			cBtn._div = jQuery('<div class="' + initClass + ' ' + jQuery(this).attr('class') + '">');
			jQuery(this).before(cBtn._div);
			cBtn._label = jQuery('label[for=' + cBtn.id + ']');
			//disabled ? 
			if (cBtn.disabled) {
				cBtn._div.addClass('disabled');
				cBtn._label.addClass('disabled');
			};
			//events
			cBtn._update = function() {
				if (jQuery(this).is(':checked')) {
					this._div.removeClass('checkboxArea');
					this._div.addClass('checkboxAreaChecked');
				} else {
					this._div.addClass('checkboxArea');
					this._div.removeClass('checkboxAreaChecked');
				};
			};
			jQuery(cBtn).change(function() {
				cBtn._update();
			}).focus(function() {
				if (!cBtn._div.hasClass('cf-focus')) {
					cBtn._div.addClass('cf-focus');
				};
			}).blur(function() {
				cBtn._div.removeClass('cf-focus checkedFocus');
			});

			cBtn._div.mouseenter(function() {
				jQuery(this).addClass('hover');
				cBtn._label.addClass('hover');
			}).mouseleave(function() {
				jQuery(this).removeClass('hover');
				cBtn._label.removeClass('hover');
			}).click(function() {
				if (!cBtn.disabled) {
					cBtn._div.addClass('cf-focus');
					jQuery(cBtn).focus();
					if (cBtn._div.hasClass('checkboxArea')) {
						cBtn.checked = true;
						jQuery(this).removeClass('checkboxArea');
						jQuery(this).addClass('checkboxAreaChecked');
					} else {
						cBtn.checked = false;
						jQuery(this).addClass('checkboxArea');
						jQuery(this).removeClass('checkboxAreaChecked');
					};
				};
			});
			//label events
			cBtn._label.mouseenter(function() {
				jQuery(this).addClass('hover');
				cBtn._div.addClass('hover');
			}).mouseleave(function() {
				jQuery(this).removeClass('hover');
				cBtn._div.removeClass('hover');
			}).click(function() {
				cBtn._div.trigger('click');
				return false;
			});
			jQuery(this).addClass('outtaHere');
		});
	};

	//get all selects
	jQuery.fn.customForm.selects = function(_this, _opt) {
		_this.selectAll = jQuery(_this).find('select').not('.outtaHere').not(_opt.disableCustomClass);
		_this.selectAll.each(function() {
			var cs = this;
			var _sopt = _opt;
			//create
			if (jQuery(cs).is(':visible')) {
				// btn build
				cs._btn = jQuery(_sopt.selectHTML);
				cs._btn.addClass(jQuery(cs).attr('class'));
				cs._btn.sText = cs._btn.find(_sopt.selectText);
				cs._btn.opener = cs._btn.find(_sopt.selectBtn + ',' + _sopt.selectText);
				var selectDisabled = cs._btn.find(_sopt.selectDisabled).hide();
				//drop build
				cs._drop = jQuery(_sopt.dropHTML);
				cs._drop.addClass('drop-' + jQuery(cs).attr('class'));
				cs._drop.optList = cs._drop.find('.csbody');
				if (jQuery(cs).attr('disabled')) selectDisabled.show();
				cs._buildDrop = function() {
					var _ul = jQuery('<ul />');
					var _selClass = '';
					jQuery(cs).find('option').each(function(ind) {
						var selOpt = jQuery(this);
						_selClass = '';
						var imgTitle = selOpt.attr("title") ? '<img src="' + selOpt.attr('title') + '" alt="img" />' : '';
						if (selOpt.is(':selected')) {
							cs._btn.sText.html(imgTitle + selOpt.html());
							_selClass = 'selected';
							if (jQuery.isFunction(_sopt.onChangeFunc)) {
								_sopt.onChangeFunc.apply(cs);
							};
						};
						var _opt = jQuery('<li class="' + selOpt.attr('class') + ' ' + _selClass + '"><a href="#">' + imgTitle + selOpt.html() + '</a></li>');
						_ul.append(_opt);
						//select one from options
						_opt.click(function() {
							cs._drop.find('a').removeClass('selected');
							jQuery(cs).find('option').removeAttr('selected');
							jQuery(this).addClass('selected');
							selOpt.attr('selected', 'selected');
							cs._btn.sText.html(imgTitle + selOpt.html());
							jQuery(cs).change();
							cs._hideDrop();
							return false;
						});
					});
					cs._drop.find('.csbody').empty().append(_ul);
				};
				//show select drop
				cs._showDrop = function() {
					cs._hideDrop();
					var _offset = cs._btn.offset();
					if (!jQuery('body').find(cs._drop).length) {
						var _width = (_sopt.dropWidth) ? 'auto' : cs._btn.innerWidth();
						cs._drop.find('.csbody').css({ overflow: 'hidden' });
						cs._drop.css({
							position: 'absolute',
							zIndex: '250',
							display: 'none',
							top: _offset.top + cs._btn.innerHeight(),
							left: _offset.left,
							width: _width
						});
						jQuery('body').append(cs._drop);
					} else {
						cs._drop.css({
							top: _offset.top,
							left: _offset.left
						});
					};
					if (_sopt.dropMaxHeight) {
						cs._drop.css({ overflow: '', visibility: 'hidden' }).show();
						if (!cs._drop.defHieght) cs._drop.defHieght = cs._drop.find('.csbody').height();
						var _opt = cs._drop.find('li');
						var _ind = _opt.index(_opt.filter('.selected'));
						if ($.browser.mozilla) {
							cs._drop.find('.csbody').animate({
								scrollTop: _opt.filter('.selected').position().top + cs._drop.find('.csbody').scrollTop() - 2
							}, 10);
						}
						if (cs._drop.defHieght > _sopt.dropMaxHeight) {
							cs._drop.find('.csbody').css({
								height: _sopt.dropMaxHeight,
								overflow: 'auto'
							});
						}
						cs._drop.css({ visibility: 'visible' });
					} else {
						cs._drop.show();
					};
					jQuery('body').get(0).activeSelect = cs;
					cs._btn.addClass('cs-opened');
				};
				//hide select drop
				cs._hideDrop = function() {
					if (jQuery('body').get(0).activeSelect) {
						jQuery('body').get(0).activeSelect._drop.hide();
						jQuery('body').get(0).activeSelect._btn.removeClass('cs-opened');
						jQuery('body').get(0).activeSelect = null;
					};
				};
				jQuery('body').click(function() {
					cs._hideDrop();
				});
				jQuery(window).resize(function() {
					if (jQuery('body').get(0).activeSelect) {
						var _offset = jQuery('body').get(0).activeSelect.offset();
						jQuery('body').get(0).activeSelect._drop.css({
							top: _offset.top + cs._btn.innerHeight(),
							left: _offset.left
						});
					}
				})
				//select events
				cs._btn.mouseenter(function() {
					jQuery(this).addClass('cs-hover');
				}).mouseleave(function() {
					jQuery(this).removeClass('cs-hover');
				});
				cs._btn.find('a').focus(function(e) {
					cs.focus();
				});
				jQuery(cs).focus(function() {
					jQuery('body').get(0).focusSelect = cs;
					cs._btn.addClass('cf-focus');
					jQuery(document).unbind('keydown').bind('keydown', function(e) {
						if (!e) evt = window.event;
						var _prevkey = e.keyCode;
						if (e.keyCode == 27) {
							cs._hideDrop();
							jQuery(cs).blur();
						} else if (e.keyCode == 13) {
							if (jQuery('body').get(0).activeSelect) {
								cs._drop.find('li.selected').trigger('click');
							} else {
								cs._buildDrop();
								cs._showDrop();
								jQuery(cs).focus();
							}
						} else if (e.keyCode == 40) {
							var _opt = cs._drop.find('li');
							var _ind = _opt.index(_opt.filter('.selected'));
							if (_ind == _opt.length - 1) {
								_opt.removeClass('selected').eq(0).addClass('selected');
								jQuery(cs).find('option').removeAttr('selected').eq(0).attr('selected', 'selected');
							} else {
								_opt.removeClass('selected').eq(_ind + 1).addClass('selected');
								jQuery(cs).find('option').removeAttr('selected').eq(_ind + 1).attr('selected', 'selected');
							}
							if (_sopt.dropMaxHeight && (cs._drop.find('.csbody').height() == _sopt.dropMaxHeight)) {
								cs._drop.find('.csbody').animate({
									scrollTop: _opt.filter('.selected').position().top + cs._drop.find('.csbody').scrollTop() - 2
								}, 10);
							};
							if (!jQuery('body').get(0).activeSelect) {
								cs._drop.find('li.selected').trigger('click');
							}
						} else if (e.keyCode == 38) {
							var _opt = cs._drop.find('li');
							var _ind = _opt.index(_opt.filter('.selected'));
							if (_ind == 0) {
								_opt.removeClass('selected').eq(_opt.length - 1).addClass('selected');
								jQuery(cs).find('option').removeAttr('selected').eq(_opt.length - 1).attr('selected', 'selected');
							} else {
								_opt.removeClass('selected').eq(_ind - 1).addClass('selected');
								jQuery(cs).find('option').removeAttr('selected').eq(_ind - 1).attr('selected', 'selected');
							}
							if (_sopt.dropMaxHeight && (cs._drop.find('.csbody').height() == _sopt.dropMaxHeight)) {
								cs._drop.find('.csbody').animate({
									scrollTop: cs._drop.find('.csbody').scrollTop() + _opt.filter('.selected').position().top - 2
								}, 10);
							};
							if (!jQuery('body').get(0).activeSelect) {
								cs._drop.find('li.selected').trigger('click');
							}
						} else if (e.keyCode == 9 || e.keyCode == 16) {
							cs._hideDrop();
						} else {
							cs._buildDrop();
							cs._showDrop();
						}
					});
				}).blur(function() {
					jQuery('body').get(0).focusSelect = null;
					cs._btn.removeClass('cf-focus');
					jQuery(document).unbind('keydown');
				});

				cs._btn.opener.mousedown(function() {
					if (jQuery('body').get(0).focusSelect) {
						jQuery('body').get(0).focusSelect._btn.removeClass('cf-focus');
						jQuery('body').get(0).focusSelect = null;
					}
					if (!cs._btn.hasClass('cs-opened')) {
						cs._buildDrop();
						cs._showDrop();
						jQuery(cs).focus();
					} else {
						cs._hideDrop();
					}
					return false;
				}).click(function() { return false; });
				cs._buildDrop();
				if (jQuery(cs).is(':visible')) {
					cs._btn.css({
						width: jQuery(cs).innerWidth()
					});
				} else {
					cs._btn.css({
						width: parseInt(jQuery(cs).css('width'), 10) + parseInt(jQuery(cs).css('paddingLeft'), 10) + parseInt(jQuery(cs).css('paddingRight'), 10) + parseInt(jQuery(cs).css('border-right-width'), 10) + parseInt(jQuery(cs).css('border-left-width'), 10)
					});
				}
				jQuery(cs).addClass('outtaHere').before(cs._btn);
			};
		});
	};

})(jQuery)
