/*
 * zCool UI 0.1 - Javascript
 *
 * Copyright (c) 2008 zhou BaiMin (zCool.cn)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * $Date: 2009-07-02 09:28:00 BeiJing $
 * $Revision: 1 $
 */
 
/* 
 import zCool.js
 import zCool.UI.js
*/

(function($, undefined){
		  
	// 基本对象
	var window = this,
	
	DOC = window.document,
	
	typeSupport = function(type){
		var input = DOC.createElement('input');
		input.setAttribute('type', type);
		return input = input.type === type;
	},
	
	FORM_ELEMENT_TAG = { INPUT:1, SELECT:1, TEXTAREA:1, BUTTON:1 },
	
	// 通常不需要验证的类型
	INPUT_RIGHT_TYPE = {
		hidden: 1,
		submit: 1,
		image: 1,
		reset: 1,
		button: 1
	},
	
	// 选择类型
	INPUT_CHOOSE_TYPE = $.INPUT_CHOOSE_TYPE = { radio:1, checkbox:1 },
	
	// <input>元素的全部类型
	// 输入字符可见的输入类型
	INPUT_HTML5_TYPE = {
		
//		hidden: 0,
//		submit: 0,
//		image: 0,
//		reset: 0,
//		button: 0,
		checkbox: 'group',
		radio: 'group',
		file: 0,
		text: 1,
		password: 1,
		search: 1,

		// 以下为 html5 新增输入类型
		tel: /^(\d+-)?\d+$/,
		
		url: /^(?:[a-zA-Z]+:\/\/)?(?:\w+\.)+\w+(?::\d+)?(?:\/|\/.+)?$/,
		
		email: /^[\w-.]+@(?:\w+\.)+\w+$/,
		
//		datetime: 1,
		
		date: /^\d{4}-(?:(?:0?2-(?:0[1-9]|[12][0-9]))|(?:0?[13578]|1[02])-(?:0?[1-9]|[1-2]\d|3[01])|(?:0?[469]|11)-(?:0?[1-9]|[1-2]\d|30))|(?:(?:(?:0[1-9]|[12][0-9])\/0?2)|(?:0?[1-9]|[1-2]\d|3[01])\/(?:0?[13578]|1[02])|(?:(?:0?[1-9]|[1-2]\d|30)\/0?[469]|11))\/\d{4}$/,
		
		month: /^(?:0?[1-9]|1[0-2])$/,
		
		week: /^(?:0?[1-9]|[1-4]\d|5[0-2])$/,
		
		time: /^(?:[0-1]\d|2[0-4]):(?:[0-5]\d):(?:[0-5]\d)$/,
		
		'datetime-local': /^$/,
		
		number: /^\d+$/,
		
		color: /^#(?:[\da-fA-F]{2}){3,4}$/,
		
		range: function(value){
			
			if( isNaN( value = Number(value) ) ){
				return false;
			}
			var min = this.getAttribute('min'),
				max = this.getAttribute('max');
				
			min = min ? Number(min) || 0 : 0;
			max = max ? Number(max) || 0 : 0;
			
			return max >= value && value >= min;
		}
	},
	
	rInputClassType = /\binput-([a-z]+)\b/,
	
	// 必填项类型集合
	INPUT_REQUIRED_TYPE = {},
	// 模式匹配类型集合
	INPUT_PATTERN_TYPE = {},
	// 选项分组
	INPUT_GROUP_TYPE = { radio:1, checkbox:1 },
	
	requiredValidClass = 'required-valid',
	requiredInvalidClass = 'required-invalid',
	patternInvalidClass = 'pattern-invalid',
	validIcoClass = 'valid-ico',
	validIcoHideClass = 'valid-ico-hide',
	chooseGroupClass = 'choose-group',
	labelCheckedClass = 'label-checked',
	requiredClass = 'required',
	invalidBlinkClass = 'invalid-blink',
	
	asyncValidLoadingClass = 'async-valid-loading',
	asyncInvalidClass = 'async-invalid',
	asyncValidInfoClass = 'async-valid-info',
	
	FORM_REQUIRED = $.attrSupport('required', 'input'),
	
	setRequired = FORM_REQUIRED ? 
	function( el, required ){
		el.required = !!required;
		$(el).prev('b.required')[required ? 'removeClass' : 'addClass']('required-off');
	} : 
	function( el, required ){
		required ? el.setAttribute('required', 'required') : el.removeAttribute('required');
		$(el).prev('b.required')[required ? 'removeClass' : 'addClass']('required-off');
	},
	
	isRequired = FORM_REQUIRED ? 
	function( el ){ return el.required; } : 
	function( el ){ return el.getAttribute('required') !== null; },
	
	isChooseRequired = {
		radio: isRequired,
		checkbox: function( el ){
			return el.getAttribute('data-required') !== null || $(el).hasClass('required');
		}
	},
	
	// 获取或创建输入验证的小图标
	getValidIco = function(el){
		return $.next(el, '.' + validIcoClass) || 
			$('<i class="' + validIcoClass + '"></i>').
				afterTo( $(el).hasClass('input-date') && $.next(el, 'a.Calendar-trigger') || el )[0];
	},
	
	// 尝试检测是否必选，若必选则设置
	//
	setGroupRequired = function( el ){
		var form = el.form;
			name = el.name,
			$inputs = name && $( form[name] );
				
		if( $inputs && $inputs.some( isChooseRequired[ el.type ] ) ){
				
			// 获取或创建选项组的目标父容器 和 验证小图标
			var target = $(el).ancestor('.' + chooseGroupClass)[0];
			if( !target ){
				return el;
			}
			
			var validIco = getValidIco( target );
			
			// 
			if( ( $input = $inputs.filter(function(input){ return input.checked; }) ).length > 0 &&
				$input.every(function(input){ return input.value; }) ){
				$( [validIco, target] ).
					removeClass( requiredInvalidClass ).
					addClass( requiredValidClass );
			}
			else{
				return $( [validIco, target] ).
					removeClass( requiredValidClass ).
					addClass( requiredInvalidClass );
			}
		}
	},
	
	// 设置关联字段
	setLinkage = function( target ){
			
		var linkageName = target.getAttribute('data-linkage-name'), 
			linkage, form;
			
		if( linkageName && (form = target.form) && (linkage = form[linkageName]) ){
			if( linkage.form === form || ((linkage = linkage[0]) && linkage.form === form) ){
				
				var checked = target.checked;
				
				switch( target.type ){
				case 'checkbox':	
					$(linkage).
						ancestor('.data-linkage')
							[checked ? 'removeClass' : 'addClass']
							('data-linkage-off');
				break;
						
				case 'radio':
					if( checked ){
						$(linkage).
							ancestor('.data-linkage')
								.removeClass('data-linkage-off');
									
						$(form[target.name]).each(function(el){
							el !== target && setLinkage(el);
						});
					}
					else{
						$(linkage).
							ancestor('.data-linkage')
								.addClass('data-linkage-off');
					}
				break;
				
				}
				
				var linkageMethod = target.getAttribute('data-linkage-method');
				switch( linkageMethod ){
				case 'input':
					var defaultValue = target.getAttribute('data-default-value');
					if( defaultValue === null){
						target.setAttribute('data-default-value', defaultValue = target.defaultValue );
					}
					
					if( checked ){
						linkage.disabled = false;
						setRequired(linkage, true);
						if( linkage.value ){
							target.value = linkage.value;
						}
						else{
							linkage.value = target.value;
							$Form.validation( linkage );
						}
					}
					else{
						linkage.disabled = true;
						setRequired(linkage, false);
						target.value = defaultValue;
					}
					
					$(linkage).blur(linkageBlur);
				break;
				}
			}
		}
	},
	
	setDefaultAttr = function(el, attr){
		var defaultAttr = el.getAttribute('data-default-' + attr);
		if( defaultValue === null){
			target.setAttribute('data-default-' + attr, defaultValue = target.defaultValue );
		}
	},
	
	linkageBlur = function(e){
		var target = e.target, form = target.form, name = target.name;
		
		$.formElements(form).some(function(el){
			if( el.getAttribute('data-linkage-name') === name ){
				el.value = target.value;
				setGroupRequired(el);
				return true;
			}
		});
	},
	
	// 元素匹配并返回placeholder值
	matchPlaceholder = function(el, nodeName, type){
		
		nodeName || (nodeName = el.nodeName);
		
		if( nodeName === 'TEXTAREA' || 
			(nodeName === 'INPUT' && INPUT_PATTERN_TYPE[ type || el.type ]) ){
				
			var p = el.getAttribute('placeholder');
			return p && p.trim();
		}
	},
	
	// 表单初始化
    $Form = $.Form = function(form){
		
		// 初始化输入占位符（html5 提示文字暗记）
		$Form.placeholder(form, true);
		
		$( form ).
			click( $Form.click ).
				focusin( $Form.focusin ).
					focusout( $Form.focusout ).
						submit( $Form.submit );
		
		// 初始化设置选项组中的默认选中项
		$Form.setFormDefaultChecked(form);
		
		return form;
	};
	
	
	$.extend($Form, {
		
        // 对表单元素（也可以是一个根元素或文档碎片中包含的多个表单元素）进行重置
		// @el <form|input|select|textarea|fragment>
		// @form <form> element
        reset: function(el){
			
    		// 若el为表单元素，直接触发其重置
			if(el.tagName == "FORM"){
				return $.triggerEvent(el, "reset");
			}
    		// 记录el在原文档中的位置
    		var parent = el.parentNode, 
				next = parent && el.nextSibling,
				form = DOC.createElement("form");
				
			form.appendChild(el);
			
			// 触发form重置
			$.triggerEvent(form, "reset");
			
			// ie 防泄漏
			return form = parent ? 
			// 若el原先位于文档中，将el放回原文档中的位置
				next ? parent.insertBefore(el, next) : parent.appendChild(el) : 
					form.removeChild(el);
        },
		
		// 获取文件选择框的信息
		// @inputFile <input type="file" class="inputFile" />
		getInputFileData: function(inputFile){
			
			/*if( inputFile.tagName != 'INPUT' || inputFile.type != 'file'){
				return null;
			}*/
			
			var files = inputFile.files, file;
			// firefox/webkit
			if(files && (file = files.item(0))){
				// webkit 暂无法获取路径
				file.filePath = file.getAsDataURL ? file.getAsDataURL() : inputFile.value;
				return file;
			}
			var data = {}, ds = DOC.selection, p;
			// IE 选区
			if(ds && ds.createRange){
				$.triggerEvent(inputFile, 'select');
				p = data.filePath = ds.createRange().text;
			}
			// 若都不支持 opera?
			else{
				p = data.filePath = inputFile.value;
			}
			// 文件名取末个斜杠后的串
			data.fileName = p.slice(p.lastIndexOf('\\') + 1);
			
			return data;
		},
		
		// 验证
		validation : function(target){
				
			// 若被隐藏
			if( target.disabled || (target.offsetWidth === 0 && target.offsetHeight === 0) ){
				return;
			}
			
			var nodeName = target.nodeName,
				validIco, pattern, value;
				
			switch( nodeName ){
				
				case 'TEXTAREA':
				value = target.value.trim();
				
				if( value && matchPlaceholder(target, nodeName) === value ){
					value = '';
				}
				if( isRequired(target) ){
					validIco = getValidIco(target);
					if( value ){
						$( [validIco, target] ).removeClass( requiredInvalidClass );
					}
					else{
						return $( [validIco, target] ).addClass( requiredInvalidClass );
					}
				}
				
				if( pattern = target.getAttribute('pattern') ){
					validIco || (validIco = getValidIco(target));
							
					if( value ){
						$( validIco ).removeClass( validIcoHideClass );
					}
					else{
						$( [validIco, target] ).removeClass( patternInvalidClass );
						$( validIco ).addClass( validIcoHideClass );
						return;
					}
					
					if( new RegExp( pattern ).test( value ) ){
						$( [validIco, target] ).removeClass( patternInvalidClass );
						return;
					}
					else{
						return $( [validIco, target] ).addClass( patternInvalidClass );
					}
				}
				return;
				
				case 'SELECT':
				if( isRequired(target) ){
					validIco = getValidIco(target);
					// 若已选，操作验证图标
					if( value = target.value.trim() ){
						$( [validIco, target] ).removeClass( requiredInvalidClass );
					}
					// 若未选直接操作返回
					else{
						return $( [validIco, target] ).addClass( requiredInvalidClass );
					}
				}
				return;
				
				case 'INPUT':
				var type =  target.getAttribute('data-type') || target.getAttribute('type') || target.type,
					hasRequired, html5;
				
				// 若为不需要验证的元素，直接返回
				if( INPUT_RIGHT_TYPE[type] ){
					return;
				}
				
				value = target.value.trim();
				
				if( value && matchPlaceholder(target, nodeName) === value ){
					value = '';
				}
				
				// 若为必填项
				if( INPUT_REQUIRED_TYPE[type] ){
					
					// 若为选项组类型
					// 尝试检测是否必选，若必选则设置
					if( INPUT_CHOOSE_TYPE[type] ){
						return setGroupRequired( target );
					}
					// 否则
					else if( isRequired(target) ){
						validIco = getValidIco(target);
						// 若已填写，操作验证图标
						if( value ){
							$( [validIco, target] ).removeClass( requiredInvalidClass );
						}
						// 若未填写直接操作返回
						else{
							return $( [validIco, target] ).addClass( requiredInvalidClass );
						}
					}
				}
				
//				if( rInputClassType.test(target.className) ){
//					type = RegExp.$1;
//				}
				
				// 若为 html5 新的输入类型
				if( html5 = INPUT_HTML5_TYPE[type] ){
					
					validIco || (validIco = getValidIco(target));
							
					if( value ){
						$( validIco ).removeClass( validIcoHideClass );
					}
					else{
						$( [validIco, target] ).removeClass( patternInvalidClass );
						$( validIco ).addClass( validIcoHideClass );
						return;
					}
					
//					switch( typeof html5 ){
//						// 若为函数，将值作为第一个参数call目标元素
//						case 'function':
//						if( html5.call( target, value ) ){
//							$( [validIco, target] ).removeClass( patternInvalidClass );
//							return;
//						}
//						else{
//							return $( [validIco, target] ).addClass( patternInvalidClass );
//						}
//						
//						// 若为正则对象，检测类型匹配		
//						case 'object':
//						if( html5.test( value ) ){
//							$( [validIco, target] ).removeClass( patternInvalidClass );
//							return;
//						}
//						else{
//							return $( [validIco, target] ).addClass( patternInvalidClass );
//						}
//					}

					// 若为正则对象，检测类型匹配
					if( html5.test ){
						if( html5.test( value ) ){
							$( [validIco, target] ).removeClass( patternInvalidClass );
							// 若同时定义了type和pattern
							// chrome以type为验证标准，firefox则以pattern为验证标准
							// return;
						}
						else{
							return $( [validIco, target] ).addClass( patternInvalidClass );
						}
					}
					// 若为函数，将值作为第一个参数call目标元素
					else if(html5.call){
						if( html5.call( target, value ) ){
							$( [validIco, target] ).removeClass( patternInvalidClass );
							// return;
						}
						else{
							return $( [validIco, target] ).addClass( patternInvalidClass );
						}
					}
					
				}
				// 若需要匹配模式
				if( INPUT_PATTERN_TYPE[type] ){
					
					if( pattern = target.getAttribute('pattern') ){
					
						validIco || (validIco = getValidIco(target));
							
						if( value ){
							$( validIco ).removeClass( validIcoHideClass );
						}
						else{
							$( [validIco, target] ).removeClass( patternInvalidClass );
							$( validIco ).addClass( validIcoHideClass );
							return;
						}
						
						if( new RegExp( pattern ).test( value ) ){
							$( [validIco, target] ).removeClass( patternInvalidClass );
							return;
						}
						else{
							return $( [validIco, target] ).addClass( patternInvalidClass );
						}
						
					}
				}
				
			}
		},
		
		asyncValid: function(target, validIco){
			
			var asyncValidURL = target.getAttribute('data-async-valid');
			
			if( !asyncValidURL ){
				return;
			}
				
			var value = target.value.trim(), targetName, 
				asyncValidInfo = $.next(target, '.' + asyncValidInfoClass);
			
			validIco || (validIco = getValidIco(target));
			$(validIco).removeClass( asyncInvalidClass );
			
			if( asyncValidInfo ){
				asyncValidInfo.style.display = 'none';
			}
			
			if( !value ){
				return;
			}
			
			if( (targetName = target.name) && asyncValidURL ){
				
				target.readOnly = true;
				$(target).addClass('readonly');
				
				$(validIco).addClass( asyncValidLoadingClass );
					
				$.ajax({
					url: asyncValidURL + (asyncValidURL.indexOf('?') > -1 ? '&': '?') + targetName + '=' + encodeURIComponent(value),
					success: function(data){
						
						//window.setTimeout(function(){
						
						target.readOnly = false;
						$(target).removeClass('readonly');
						
						$(validIco).removeClass( asyncValidLoadingClass );
						
						if( data !== 'y' ){
							$(validIco).addClass( asyncInvalidClass );
							if( data ){
								if( asyncValidInfo ){
									asyncValidInfo.style.display = '';
									asyncValidInfo.innerHTML = data;
								}
								else{
									$('<span class="' + asyncValidInfoClass + '">' + data + '</span>').afterTo(validIco);
								}
							}
						}
						
						//}, 1000);
					}
				});
			}
		},
		
		// html5 required、type、pattern验证
		click: function(e){
			var target = e.target, type = target.type;
			if( target.nodeName === 'INPUT' && INPUT_CHOOSE_TYPE[type]){
				
				switch( type ){
					
				case 'checkbox':
					$(target).
						ancestor('label')
							[ target.checked ? 'addClass' : 'removeClass' ]
								( labelCheckedClass );
				
					// 尝试检测是否必选，若必选则设置
					setLinkage(target);
					setGroupRequired(target);
				break;
				
				case 'radio':
					var name = target.name;
					if( name ){
						$( target.form[name] ).
							ancestor('label').
								removeClass( labelCheckedClass );
						$( target ).
							ancestor('label').
								addClass( labelCheckedClass );
					}
				
					// 尝试检测是否必选，若必选则设置
					setLinkage(target);
					setGroupRequired(target);
				break;
					
				}
			}
		},
		
		// html5 required、type、pattern 验证
		focusout: function(e){
			$Form.validation.call(e, e.target);
		},
		
		// 自定义异步验证
		focusin: function(e){
			var target = e.target, tagName = target.tagName;
			
			if( (tagName === 'TEXTAREA' || 
				(tagName === 'INPUT' && !INPUT_CHOOSE_TYPE[ target.type ])) && 
				target.getAttribute('data-async-valid') ){
					
				$(target).change( $Form.change );
			}
		},
		
		// 自定义异步验证
		change: function(e){
			$Form.asyncValid( e.target );
		},
		
		// 表单提交时的验证
		submit: function(e){
			
			var el = $.formElements(this).filter($Form.validation, e)[0];
			// 若有未通过验证的项
			if( el ){
				e.preventDefault();
				if( INPUT_CHOOSE_TYPE[ el.type ] ){
					if( !(el = $(el).ancestor('.' + chooseGroupClass)[0]) ){
						return;
					}
				}
				if( !$.isParentFixed(el) ){
					$( window ).scrollTop( $.coord(el).top - 10 );
				}
				//alert( $.coord(el).top - 10 );
				try{
					$(el).focus();
				}
				catch(e){
					//alert(e);
				}
				var i = 0;
				window.setTimeout( function(){
					if(i++ < 12){
						$(el).toggleClass(invalidBlinkClass);
						window.setTimeout(arguments.callee, 50);
					}
				}, 50);
			}
		},
		
		setFormDefaultChecked: function(form){
			
			$.formElements( form ).each(function(el){
					
				var elName = el.name;
					
				if( elName && this.indexOf(elName) < 0 && INPUT_CHOOSE_TYPE[ el.type ] ){
						
					this.push( elName );
					$Form.setDefaultChecked( form[elName] );
				}
					
			}, []);
		},
		
		// 为一个选项组初始化选中项
		setDefaultChecked: function( els, values ){
			
			var type = els[0].type;
			
			var TYPE_DEFAULT_VALUE_ATTR = {
				checkbox: 'data-checkbox-default-values',
				radio: 'data-radio-default-value'
			};
			
			if( INPUT_CHOOSE_TYPE[ type ] && 
				(values || 
				(values = 
					els[0].getAttribute('data-default-value') || 
					els[0].getAttribute( TYPE_DEFAULT_VALUE_ATTR[ type] )
				)) ){
					
				switch(type){
					
				case 'checkbox':
				
				$( els ).filter(function( el ){
					var value = el.value, index = this.indexOf( el.value );
					if( index > -1 ){
						el.checked = el.defaultChecked = true;
						setLinkage(el);
						this.splice(index, 1);
					}
					else{
						return !value;
					}
				}, values = values.split(',')).
				each(function(el, i){
					
					if( this[i] ){
						el.value = this[i];
						el.checked = el.defaultChecked = true;
					}
					setLinkage(el);
					
				}, values);
				
				break;
				
				case 'radio':
				$( els ).some(function( el ){
					
					if( el.value === values ){
						el.checked = el.defaultChecked = true;
						setLinkage(el);
						return true;
					}
				});
				break;
				};
			}
		},
		
		setTypesGroupRequired: function(form, names){
			
			if( names.some(function(name){
					var el = this[name];
					return el && (el.nodeType ? el.value.trim() : $(el).some(function(e){ return e.checked }) )
				}, form) ){
			}
		},
		
		/*
		<input type="text" placeholder="请输入" />
		<textarea placeholder="请输入" />
		使用方法（支持HTML5该属性的会选择忽略执行该方法）：
		$.Form.placeholder && $.Form.placeholder(form);
		*/
        // 隐藏/显示输入框内的文本提示
        placeholder: $.attrSupport('placeholder', 'input') ? $.noop : 
		
		(function(){
			
			// 元素匹配并返回placeholder值
			var match = matchPlaceholder,
			
			// 定义提示文字样式类
			blurClass = 'placeholder',
			
			// 聚焦事件（可委托）
			focusin = function(e){
				clear(e.target);
			},
				
			// 失焦事件
			focusout = function(e){
				init(e.target);
			},
			
			submit = function(e){
				$.formElements(this).forEach(clear);
			},
				
			// 初始化
			init = function( el ){
				var p = match(el, el.nodeName);
				if( p && !el.value.trim() ){
					el.value = p;
					$(el).addClass(blurClass);
				}
			},
			
			// 清除
			clear = function( el ){
				var p = match(el, el.nodeName);
				if( p && p === el.value.trim() ){
					el.value = '';
					$(el).removeClass(blurClass);
				}
			};
				
			// @form element
			// @enable boolean true -> 独立注册聚焦事件, false-> 忽略（聚焦事件已委托给前辈元素注册）
			return function(form, enable){
				
				var nodeName = form.nodeName, p;
				
				if( nodeName === 'FORM' ){
					if(enable){
						$(form).focusin(focusin).focusout(focusout).submit(submit);
						$.formElements(form).forEach(init);
					}
					else{
						$.formElements(form).forEach(clear);
					}
				}
				else{
					enable ? init( form ) : clear( form );
				}
			}
			
		})(),
		
        // input/textarea 自适应尺寸
        inputAutoSize: function(el, minWidth, minHeight, maxWidth, maxHeight){
			
			var style = el.style, sw, sh;
			
			switch(el.tagName){
				case 'TEXTAREA':
					var pl = parseInt($.finalStyle(el, 'padding-left')), 
						pr = parseInt($.finalStyle(el, 'padding-right'));
					style.width = ((sw = el.scrollWidth) >= minWidth ? maxWidth ? sw < maxWidth ? sw : maxWidth : sw : minWidth) + 'px';
						
					var pt = parseInt($.finalStyle(el, 'padding-top')), 
						pb = parseInt($.finalStyle(el, 'padding-bottom'));
					style.height = ((sh = el.scrollHeight) >= minHeight ? maxHeight ? sh < maxHeight ? sh : maxHeight : sh : minHeight) + 'px';
					break;
				case 'INPUT':
					if(el.type == 'text' && maxWidth){
						var pl = parseInt($.finalStyle(el, 'padding-left')), 
							pr = parseInt($.finalStyle(el, 'padding-right'));
						style.width = ((sw = el.scrollWidth) >= minWidth ? maxWidth ? sw < maxWidth ? sw : maxWidth : sw : minWidth) + 'px';
					}
					break;
			}
        }
	});
	
	$.extend($Form, {
		typeSupport: typeSupport,
		FORM_REQUIRED: FORM_REQUIRED,
		FORM_ELEMENT_TAG: FORM_ELEMENT_TAG,
		INPUT_RIGHT_TYPE: INPUT_RIGHT_TYPE,
		INPUT_CHOOSE_TYPE: INPUT_CHOOSE_TYPE,
		INPUT_HTML5_TYPE:　INPUT_HTML5_TYPE,
		INPUT_REQUIRED_TYPE:　INPUT_REQUIRED_TYPE,
		INPUT_PATTERN_TYPE: INPUT_PATTERN_TYPE,
		INPUT_GROUP_TYPE: INPUT_GROUP_TYPE,
		
		requiredValidClass: requiredValidClass,
		requiredInvalidClass: requiredInvalidClass,
		patternInvalidClass: patternInvalidClass,
		validIcoClass: validIcoClass,
		validIcoHideClass: validIcoHideClass,
		chooseGroupClass: chooseGroupClass,
		labelCheckedClass: labelCheckedClass,
		requiredClass: requiredClass,
		invalidBlinkClass: invalidBlinkClass,
		asyncValidLoadingClass: asyncValidLoadingClass,
		asyncInvalidClass: asyncInvalidClass,
		asyncValidInfoClass: asyncValidInfoClass,
		
		setRequired: setRequired,
		isRequired: isRequired,
		getValidIco: getValidIco,
		setGroupRequired: setGroupRequired,
		setLinkage: setLinkage,
		matchPlaceholder: matchPlaceholder
	});
	
	// 获取表单元素的zCool集合
	$.formElements = function(form){
		var $z = $();
		$z.context = form;
		if( form.tagName === 'FORM' ){
			return $.concatNodes($z, form.elements);
		}
		else{
			var els = form.getElementsByTagName('*'), i = -1, el, l = 0;
			while( el = els[++i] ){
				if( FORM_ELEMENT_TAG[ el.tagName ] ){
					$z[l++] = el;
				}
			}
			$z.length = l;
			return $z;
		}
	};
	
	// 获取<select>元素选项的zCool集合
	$.selectOptions = function(select){
		var $z = $();
		$z.context = select;
		return $.concatNodes($z, select.options);
	};
	
	(function(h, type){
		
		//$.FORM_PATTERN = $.attrSupport('pattern', 'input');
			
		h.datetime = h.date.source + ' ' + h.time.source;
			
		for( type in h ){
			
			// 若默认不支持 required
			//$.FORM_REQUIRED || (INPUT_REQUIRED_TYPE[ type ] = 1);
			INPUT_REQUIRED_TYPE[ type ] = 1;
			
			// pattern
			if( h[ type ] && typeof h[ type ] !== 'string' ){
				INPUT_PATTERN_TYPE[ type ] = 1;
			}
		}
		
	})(INPUT_HTML5_TYPE);
	
	
})(zCool);

