/*
 * --------------------------------------------------------
 *   JavaScript Libary to Control the New/Edit Fields
 *   
 *  Author: DuWei (Erucy), MVP of SharePoint Services
 *  Version: 1.0
 *  LastMod: 2009-2-2
 * --------------------------------------------------------
 */

/*
 * initial fields collection
 * return: fields dictionary
 * 	key: field name (display name)
 * 	value: tr element of the field input control
 */
function init_fields(){
  var res = {};
  $("td.ms-formlabel").each(function(){
	  if($(this).find('h3 nobr').length == 0) return;
	  var nm = $(this).text();
	  if(nm.indexOf('*') > -1) nm = nm.substring(0, nm.indexOf('*'));
	  res[$.trim(nm)] = this.parentNode;
  });
  return res;
}

/*
 * hide a field
 * 	fields: fields dictionary
 * 	sName: field to hide, display name used
 */
function hideField(fields, sName){
  if(fields[sName] != undefined)
    $(fields[sName]).hide();
}

/*
 * Get field value
 * fields: fields dictionary
 * sName: field to get
 * sType: type of the field
 * bLoading: true to get the value in load state(default), false to get in edit state
 */
function getFieldValue(fields, sName, sType, bLoading){
	if(fields[sName] == undefined) return null;
	var value = '';
	var $field = $(fields[sName]).find('.ms-formbody');
	switch(sType){
		case 'plain':
			if(!browseris.ie5up || !browseris.win32 || IsAccessibilityFeatureEnabled())
				value = $field.find('textarea:eq(0)').val();
			else
				value = $field.find('textarea:eq(0)').html();
			break;
		case 'html':
			if(!browseris.ie5up || !browseris.win32 || IsAccessibilityFeatureEnabled())
				value = $field.find('textarea:eq(0)').val();
			else if(bLoading == undefined || bLoading == true)
				value = $field.find('textarea:eq(0)').text();
		    else
				value = $field.find('.ms-rtelong').contents().find('body').html();
			break;
		case 'choice':
			value = $field.find('select:eq(0)').val();
			break;
		case 'radio':
			$field.find('.ms-RadioText').each(function(){
				if($(this).find('input:eq(0)').attr('checked')){
					value = $(this).text(); return false;
				}
			});
			break;
		case 'checklist':
			$field.find('.ms-RadioText').each(function(){
				if($(this).find('input:eq(0)').attr('checked')){
					if(value == '') value = $(this).text();
					else value += ';#' + $(this).text();
				}
			});
			break;
		case 'datetime':
			value = $field.find('input:text').val();
			value += ' ';
			value += $field.find('select:eq(0)').val();
			value += $field.find('select:eq(1)').val();
			break;
		case 'lookup':
			if($field.find('img').length > 0){
				var inpt = $field.find('.ms-lookuptypeintextbox');
				value = $('#' + inpt.attr('optHid')).val() + ';#' + inpt.val();
			}else{
				var opt = $field.find('select option:selected').get(0);
				if(opt.value != '0')
					value = opt.value + ';#' + opt.text;
			}
			break;
		case 'multilookup':
			if(bLoading == undefined || bLoading == true){
				value = $field.find('input:hidden[id$="Picker_initial"]').val().replace(/\|t/g, ';#');
			}else{
				var slt = $field.find('select').get(1);
				for(var i=0; i<slt.options.length; i++){
					if(value == '') value = slt.options[i].value + ';#' + slt.options[i].text;
					else value += ';#' + slt.options[i].value + ';#' + slt.options[i].text;
				}
			}
			break;
		case 'bool':
			value = $field.find('input:eq(0)').attr('checked');
			break;
		case 'link':
		case 'pic':
			value = $field.find('input:eq(0)').val() + ', ' + $field.find('input:eq(1)').val();
			break;
		case 'person':
			if(bLoading == undefined || bLoading == true)
				value = $field.find('input:eq(0)').val();
			else{
				 $field.find('.ms-entity-resolved').each(function(){
					 if(!browseris.ie5up || !browseris.win32 || IsAccessibilityFeatureEnabled()){
						 var $ent = $(this).find('#divEntityData');
						 if(value == '') value = $ent.attr('description') + ';#' + $ent.attr('displaytext');
						 else value += ';#' + $ent.attr('description') + ';#' + $ent.attr('displaytext');
					 }else{
						var data = this.firstChild.firstChild.data;
						if(data != ''){
							var pos = data.indexOf('>DisplayName</Key>') + 47;
							var name = data.substring(pos, data.indexOf('</Value>', pos));
							pos = data.indexOf('>SPUserID</Key>') + 44;
							if(pos == 43) pos = data.indexOf('>SPGroupID</Key>') + 45;
							var id = data.substring(pos, data.indexOf('</Value>', pos));
							if(value == '') value = id + ';#' + name;
							else value += ';#' + id + ';#' + name;
						}
					 }
				});
			}
			break;
		case 'num':
		case 'percent':
			value = $field.find('input:eq(0)').val().split(',').join('');
			break;
		case 'text':
		case 'date':
		default:	 // text, number, date
			value = $field.find('input:eq(0)').val();
			break;
	}
	return value;
}

/*
 * readonly a field, hide the control and display the value
 * 	fields: fields dictionary
 * 	sName: field to readonly, display name used
 * 	sType: type of the field
 */
function readonlyField(fields, sName, sType, bLoading, resTrueFalse){
  if(fields[sName] == undefined) return;
  var $field = $(fields[sName]).find('.ms-formbody');
  var value = getFieldValue(fields, sName, sType, bLoading);
  var $valueDiv = $("<div></div>");
  switch(sType){
	case 'percent':
		$valueDiv.html($field.find('input:eq(0)').val() + '%');
		break;
	case 'checklist':
		$valueDiv.text(value.replace(/;#/g, '; '));
		break;
	case 'lookup':
	case 'multilookup':
	case 'person':
		var tmp = '';
		var sep = value.split(';#');
		for(var i=0; i<sep.length; i+=2){
			if(tmp == '') tmp = sep[i+1];
			else tmp += '; ' + sep[i+1];
		}
		$valueDiv.text(tmp);
		break;
	case 'bool':
		if(resTrueFalse == undefined){
			if(value) $valueDiv.html('是');
			else $valueDiv.html('否');
		}else{
			var sep = resTrueFalse.split('|');
			if(value) $valueDiv.text(sep[0]);
			else $valueDiv.text(sep[1]);
		}
		break;
	case 'pic':
		if($.trim(value) != '' && $.trim(value) != 'http://,' && $.trim(value) != 'https://'){
			var sep = value.split(', ');
			var $img = $("<img/>");
			$img.attr('src', sep[0]).attr('title', sep[1]);
			$valueDiv.append($img);
		}
		break;
	case 'link':
		if($.trim(value) != '' && $.trim(value) != 'http://,' && $.trim(value) != 'https://'){
			var sep = value.split(', ');
			var $a = $("<a/>");
			$a.attr('href', sep[0]).attr('title', sep[1]).text(sep[1]);
			$valueDiv.append($a);
		}
		break;
	case 'num':
		$valueDiv.html($field.find('input:eq(0)').val());
		break;
	case 'html':
	case 'plain':
	case 'date':
	case 'datetime':
		$valueDiv.html(value);
		break;
	case 'text':
	case 'choice':
	case 'radio':
	default:
		$valueDiv.text(value);
		break;
  }
  $field.children().hide();
  $field.prepend($valueDiv);
}

/*
 * set field value
 * 	fields: fields dictionary
 * 	sName: field to readonly, display name used
 * 	sType: type of the field:
 * 		person: user and group field, only works after loading
 * 	sValue: value to set
 */
function setFieldValue(fields, sName, sType, sValue, bLoading){
  if(fields[sName] == undefined) return;
  var $field = $(fields[sName]).find('.ms-formbody');
  switch(sType){
	  case 'multilookup':
		  if(bLoading == undefined || bLoading == true){
			var sep = $field.find('input:hidden[id$="Picker_data"]').val().split('|t');
			var vl = '';
			for(var i=0; i<sep.length; i+=4){
				if($.inArray(parseInt(sep[i]), sValue) > -1){
					if(vl == '') vl = sep[i] + '|t' + sep[i+1];
					else vl += '|t' + sep[i] + '|t' + sep[i+1];
				}
			}
			$field.find('input:hidden[id$="Picker_initial"]').val(vl);
		  }else{
			  var $slfrom = $field.find('select:eq(0)'), $slto = $field.find('select:eq(1)');
			  var mstr = eval($field.find('input:hidden:eq(0)').attr('id') + '_m');
			  // clear
			  $slto.find('option').attr('selected', true);
			  GipRemoveSelectedItems(mstr);
			  // reset
			  $slfrom.find('option').each(function(){
				  $(this).attr('selected', ($.inArray(parseInt($(this).attr('value')), sValue) > -1));
			  });
			  GipAddSelectedItems(mstr);
		  }
		  break;
	  case 'lookup':
		  if($field.find('img').length == 0)
			$field.find('select').val(sValue);
		  else{
			  var $inpt = $field.find('.ms-lookuptypeintextbox');
			  var sep = $inpt.attr('choices').split('|');
			  for(var i=0; i<sep.length; i+=2){
				  if(sep[i+1] == sValue){
					  $inpt.val(sep[i]); break;
				  }
			  }
			  $('#' + $inpt.attr('optHid')).val(sValue);
		  }
		  break;
	  case 'datetime':
		  var sep = sValue.split(' ');
		  $field.find('input:eq(0)').val(sep[0]);
		  sep = sep[1].split(':');
		  if(sep[0].toString().length == 1) sep[0] = '0' + sep[0];		// x -> 0x
		  sep[0] += ':';
		  $field.find('select:eq(0)').val(sep[0]);
		  $field.find('select:eq(1)').val(sep[1]);
		  break;
	  case 'checklist':
		  $field.find('.ms-RadioText').each(function(){
			$(this).find('input:eq(0)').attr('checked', ($.inArray($(this).text(), sValue) > -1));
		  });
		  break;
	  case 'radio':
		  $field.find('.ms-RadioText').each(function(){
			if($(this).text() == sValue){
				$(this).find('input:eq(0)').attr('checked', true);
				return false;
			}
		  });
		  break;
	  case 'choice':
		  $field.find('select:eq(0)').val(sValue);
		  break;
	  case 'html':
		  if(bLoading == undefined || bLoading == true || (!browseris.ie5up || !browseris.win32 || IsAccessibilityFeatureEnabled()))
		      $field.find('textarea:eq(0)').text(sValue);
	      else
			  $field.find('.ms-rtelong').contents().find('body').html('<div>' + sValue + '</div>');
		  break;
	  case 'plain':
		  $field.find('textarea:eq(0)').text(sValue);
		  break;
	  case 'person':
		  if(bLoading == false){
			  if(!browseris.ie5up || !browseris.win32 || IsAccessibilityFeatureEnabled()){
				  $field.find('textarea:eq(0)').attr('value', sValue);
				  $field.find('textarea:eq(0)').keyup();
			  }else{
				  $field.find('.ms-inputuserfield').html(sValue);
			  }
	      }
	      else
			  alert(sName + ' will not set in the loading state.');
		  break;
	  case 'link':
	  case 'pic':
		  var v1 = '', v2 = '';
		  if(sValue != null && sValue != undefined){
			  var sep = sValue.split(', ');
			  v1 = sep[0];
			  if(sep.length > 0) v2 = sValue.substr(v1.length + 2);
		  }
		  $field.find('input:eq(0)').val(v1);
		  $field.find('input:eq(1)').val(v2);
		  break;
	  case 'bool':
		  $field.find('input:eq(0)').attr('checked', sValue);
		  break;
	  case 'text':
	  case 'num':
	  case 'percent':
	  case 'date':
	  default:
	    $field.find('input:eq(0)').val(sValue);
		break;
  }
}

/*
 * set linkage to 2 choice fields
 * 	fields: fields dictionary
 * 	mainFieldName: name of the main field, [display name]
 * 	subFieldName: name of the sub field, [display name]
 * 	mapListName: the list save the map between two fields
 * 	mapMainField: main field in the map list, [internal name]
 * 	mapSubField: sub field in the map list, [internal name]
 */ 
function linkageChoices(fields, mainFieldName, subFieldName, mapListName, mapMainField, mapSubField){
	if(fields[mainFieldName] == undefined || fields[subFieldName] == undefined) return;
	var $mainSelect = $(fields[mainFieldName]).find('select'),
		$subSelect = $(fields[subFieldName]).find('select');
	var origValue = '';
	$subSelect.find('option').each(function(){
		origValue += $(this).text() + ';#';
	});
	if(origValue != '') origValue = origValue.substr(0, origValue.length - 2);
	var sepOrigValue = origValue.split(';#');

	var subValue = $subSelect.find('option:selected').text();
	$mainSelect.change(function(){
		var subSelect = $subSelect.get(0);
		var mainValue = $mainSelect.find('option:selected').text().replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
		if(mainValue == ''){
			subSelect.innerHTML = '';
			for(var i=0; i<sepOrigValue.length; i++) subSelect[subSelect.options.length] = new Option(sepOrigValue[i], sepOrigValue[i]);
			$subSelect.change(function(){
				var subValue = $subSelect.find('option:selected').text().replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
				var query = "<Where><Eq><FieldRef Name='" + mapSubField + "' /><Value Type='Text'>" + subValue + "</Value></Eq></Where>";
				var res = queryItems(mapListName, query, [mapMainField]);
				if(res.count <= 0) return;
				$mainSelect.val(res.items[0][mapMainField]);
				$mainSelect.change();
				$subSelect.val(subValue.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&'));
			});
		} else {
			subSelect.innerHTML = '';
			var query = "<Where><Eq><FieldRef Name='" + mapMainField + "' /><Value Type='Text'>" + mainValue + "</Value></Eq></Where>";
			query += "<OrderBy><FieldRef Name='" + mapSubField + "' /></OrderBy>";
			var res = queryItems(mapListName, query, [mapSubField]);
			$.each(res.items, function(idx, item){
				subSelect[subSelect.options.length] = new Option(item[mapSubField], item[mapSubField]);
			});
			var mainSelect = $mainSelect.get(0);
			$subSelect.unbind('change');
		}
	});
	$subSelect.change(function(){
		var subValue = $subSelect.find('option:selected').text().replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
		var query = "<Where><Eq><FieldRef Name='" + mapSubField + "' /><Value Type='Text'>" + subValue + "</Value></Eq></Where>";
		var res = queryItems(mapListName, query, [mapMainField]);
		if(res.count <= 0) return;
		$mainSelect.val(res.items[0][mapMainField]);
		$mainSelect.change();
	    $subSelect.val(subValue.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&'));
	});
	$subSelect.val(subValue);
}

/*
 * set linkage to 2 lookup fields
 * 	fields: fields dictionary
 * 	mainFieldName: name of the main field, [display name]
 * 	subFieldName: name of the sub field, [display name]
 * 	mapListName: the list save the map between two fields
 * 	mapMainField: main field in the map list, [internal name]
 * 	mapSubField: sub field in the map list, [internal name]
 * displayText: the text of the "filter" link
 */ 
function linkageLookups(fields, mainFieldName, subFieldName, mapListName, mapMainField, mapSubField, displayText){
	if(fields[mainFieldName] == undefined || fields[subFieldName] == undefined) return;
	if(displayText == undefined || displayText == null) displayText = '筛选';
	var $filter = $("<a href='javascript:void(0)'></a>");
	var $mainPart = $(fields[mainFieldName]).find('.ms-formbody'), $subPart = $(fields[subFieldName]).find('.ms-formbody');
	var mainType, subType;
	if($mainPart.find('img').length > 0) mainType = 'complex';
	else mainType = 'simple';
	if($subPart.find('select').length > 1) subType = 'multi';
	else if($subPart.find('img').length > 0) subType = 'complex';
	else subType = 'simple';

	// all sub
	var origSubs = [], subMultiData, subMstr;
	if(subType == 'complex') origSubs = $subPart.find('.ms-lookuptypeintextbox').attr('choices').split('|');
	else if(subType == 'simple'){
		$subPart.find('option').each(function(){
			origSubs.push($(this).text());
			origSubs.push($(this).attr('value'));
		});
	}else{
		subMstr = eval($subPart.find('input:hidden:eq(0)').attr('id') + '_m');
		subMultiData = $subPart.find('input:hidden[id$="Picker_data"]').val();
		var tmp = subMultiData.split('|t');
		for(var i=0; i<tmp.length; i+=4){
			origSubs.push(tmp[i+1]);
			origSubs.push(tmp[i]);
		}
	}
	var isLoading = true;

	// click
	$filter.text(displayText).click(function(){
		var lkid = -1;
		if(mainType == 'simple') lkid = $mainPart.find('select:eq(0)').val();
		else lkid = $('#' + $mainPart.find('.ms-lookuptypeintextbox').attr('optHid')).val();
		if(lkid < 0) return;	// failed

		var oldSlt = null;
		if(subType == 'simple') oldSlt = $subPart.find('select:eq(0)').val();
		else if(subType == 'multi'){
			oldSlt = new Array();
			$subPart.find('select:eq(1)').find('option').each(function(){
				oldSlt.push($(this).attr('value'));
			});
		}

		if(lkid == 0){	 // restore original
			if(isLoading) return;
			if(subType == 'complex') $subPart.find('.ms-lookuptypeintextbox').attr('choices', origSubs.join('|'));
			else{
				var slt = $subPart.find('select').get(0);
				slt.innerHTML = '';
				if(subType == 'simple'){
					for(var i=0; i<origSubs.length; i+=2)
						slt.options[slt.options.length] = new Option(origSubs[i], origSubs[i+1]);
				}else{
					for(var i=0; i<origSubs.length; i+=2)
						if($.inArray(origSubs[i+1], oldSlt) < 0)
							slt.options[slt.options.length] = new Option(origSubs[i], origSubs[i+1]);
					subMstr.data = GipGetGroupData(subMultiData);
				}
			}
		}else{	 // select
			var res = queryItems(mapListName, "<Where><Eq><FieldRef Name='" + mapMainField + "' LookupId='TRUE'/><Value Type='Lookup'>" + lkid + "</Value></Eq></Where>", ['ID', mapSubField]);
			if(res.count > -1){
				var sep = [];
				if(origSubs.length > 1 && origSubs[1].toString() == '0'){
					sep.push(origSubs[0]); sep.push(origSubs[1]);	// (NULL) selection
				}
				if(subType == 'multi'){
					$.each(res.items, function(idx, itm){
						if($.inArray(itm['ID'], oldSlt) < 0){
							sep.push(itm[mapSubField]);
							sep.push(itm['ID']);
						}
					});
				}else{
					$.each(res.items, function(idx, itm){
						sep.push(itm[mapSubField]);
						sep.push(itm['ID']);
					});
				}

				if(subType == 'complex'){
					$subPart.find('.ms-lookuptypeintextbox').attr('choices', sep.join('|'));
					if(!isLoading) $subPart.find('img').click();
				}
				else if(subType == 'multi' && isLoading){
					var tmp = [];
					for(var i=0; i<sep.length; i+=2)
						tmp.push(sep[i+1] + '|t' + sep[i] + '|t |t ');
					$subPart.find('input:hidden[id$="Picker_data"]').val(tmp.join('|t'));
				}else{
					var slt = $subPart.find('select').get(0);

					slt.innerHTML = '';
					for(var i=0; i<sep.length; i+=2)
						slt.options[slt.options.length] = new Option(sep[i], sep[i+1]);
					if(isLoading && subType == 'simple') $(slt).val(oldSlt);
				}

				// multi data
				if(subType == 'multi' && !isLoading){
					var tmp = [];
					$subPart.find('option').each(function(){
						tmp.push($(this).attr('value'));
						tmp.push($(this).text());
						tmp.push(' |t ');
					});
					var newValue = tmp.join('|t');
					$subPart.find('input:hidden[id$="Picker_data"]').val(newValue);
					subMstr.data = GipGetGroupData(newValue);
				}
			}
		}
	});

	var $pos;
	if(mainType == 'complex') $pos = $mainPart.find('img:eq(0)');
	else $pos = $mainPart.find('select:eq(0)');
	$pos.after($filter).after("&nbsp;&nbsp;");
	$filter.click();
	isLoading = false;
}

/*
 * filter drop down choice or lookup field by "contains"
 * fields: fields dictionary
 * sName: field to filter
 * displayText: text of the "filter" link
 */
function filterLookupChoice(fields, sName, displayText){
	if(fields[sName] == undefined) return;
	var $filter = $("<a href='javascript:void(0)'></a>");
	if(displayText == undefined || displayText == null) displayText = '筛选';
	var fldType, $fieldPart = $(fields[sName]).find('.ms-formbody');
	var origValues = [];
	if($fieldPart.find('img').length > 0){
		fldType = 'complex';
		origValues = $fieldPart.find('.ms-lookuptypeintextbox').attr('choices').split('|');
	}
	else if($fieldPart.find('select').length > 1){
		fldType = 'multi';
		var tmp = $fieldPart.find('input:hidden[id$="Picker_data"]').val().split('|t');
		for(var i=0; i<tmp.length; i+=4){
			origValues.push(tmp[i+1]);
			origValues.push(tmp[i]);
		}
	}
	else if($fieldPart.find('select').length > 0){
		fldType = 'simple';
		$fieldPart.find('option').each(function(){
			origValues.push($(this).text());
			origValues.push($(this).attr('value'));
		});
	}
	else return;

	$filter.text(displayText).click(function(){
		var kw = $(this).parent().find('input:eq(0)').val();
		var fltValues;
		if($.trim(kw) == '') fltValues = origValues;
		else{
			fltValues = new Array();
			for(var i=0; i<origValues.length; i+=2){
				if(origValues[i].indexOf(kw) > -1){
					fltValues.push(origValues[i]);
					fltValues.push(origValues[i+1]);
				}
			}
		}

		if(fldType == 'multi'){
			var alreadyValues = [];
			$fieldPart.find('select:eq(1)').find('option').each(function(){
				alreadyValues.push($(this).attr('value'));
			});
			var slt = $fieldPart.find('select').get(0), tmp = [];
			slt.innerHTML = '';
			for(var i=0; i<fltValues.length; i+=2){
				if($.inArray(fltValues[i+1], alreadyValues) < 0)
					slt.options[slt.options.length] = new Option(fltValues[i], fltValues[i+1]);
			}
			$fieldPart.find('option').each(function(){
				tmp.push($(this).attr('value') + '|t' + $(this).text()+ '|t |t ');
			});
			var newdata = tmp.join('|t');
			$fieldPart.find('input:hidden[id$="Picker_data"]').val(newdata);
 		    var mstr = eval($fieldPart.find('input:hidden:eq(0)').attr('id') + '_m');
			mstr.data = GipGetGroupData(newdata);
		}else{
			if(fldType == 'simple'){
				var slt = $fieldPart.find('select').get(0);
				slt.innerHTML = '';
				for(var i=0; i<fltValues.length; i+=2)
					slt.options[slt.options.length] = new Option(fltValues[i], fltValues[i+1]);
			}else{
				$fieldPart.find('.ms-lookuptypeintextbox').attr('choices', fltValues.join('|'));
			}
		}
	});

	var $inpt = $("<input type='text' class='ms-input'/>");
	$inpt.keypress(function(event){
		if(event.keyCode == 13){
			$filter.click();
			if ( event && event.stopPropagation )
				event.stopPropagation();
			else
				window.event.cancelBubble = true;
			return false; 
		}
	});

	var $div = $("<div></div>");
	$div.append($inpt); $div.append("&nbsp;"); $div.append($filter);
	$(fields[sName]).find('.ms-formbody').prepend($div);
}

/*
 * check if the fields are empty
 * fields: field dictionary
 * checkFields: fields to check
 * fldTypes: types of the fields
 * emptyCaution: when empty, the caution text to display
 */
function checkEmpty(fields, checkFields, fldTypes, emptyCaution){
  var pass = true;
  if(emptyCaution == undefined || emptyCaution == null)
	  emptyCaution = "必须为此必填字段指定值。";
  $.each(checkFields, function(idx, fldName){
    var fldType = fldTypes[idx];
	var $container = $(fields[fldName]).find('.ms-formbody');
	if(fldType == 'html' && (!browseris.ie5up || !browseris.win32 || IsAccessibilityFeatureEnabled())) fldType = 'plain';
  	if(fldType == 'html'){
		var $fld = $container.find('.ms-rtelong').contents().find('body');
		if($fld.text() == ''){
			pass = false;
			if($container.find('.ms-formvalidation').length == 0)
				$container.append($("<div class='ms-formvalidation'>" + emptyCaution + "</div>"));
			$fld.focus();
		}else{
			$container.find('.ms-formvalidation').remove();
		}
	} else if(fldType == 'person'){
		var $fld, ok = false;
		if(!browseris.ie5up || !browseris.win32 || IsAccessibilityFeatureEnabled()){
			$fld = $container.find('textarea:eq(0)');
			ok = ($.trim($fld.val()) != '');
		}else{
			$fld = $container.find('.ms-inputuserfield');
			ok = ($.trim($fld.text()) != '');
		}
		if(!ok){
			pass = false;
			if($container.find('.ms-formvalidation').length == 0)
			    $container.append($("<div class='ms-formvalidation'>" + emptyCaution + "</div>"));
			$fld.focus();
		}else{
			$container.find('.ms-formvalidation').remove();
		}
	} else{
		var $fld, inptValue = '';
		switch(fldType){
			case 'radio':
			case 'bool':
				inptValue = 'impossible empty';
				break;
			case 'checklist':
				$fld = $container.find('input:checkbox:eq(0)');
				if($container.find('input:checked').length > 0) inptValue = 'filled';
				break;
			case 'multilookup':
				$fld = $container.find('select:eq(0)');
				if($container.find('select:eq(1)').find('option').length > 0) inptValue = 'filled';
				break;
			case 'lookup':
				if($container.find('img').length > 0){
					$fld = $container.find('.ms-lookuptypeintextbox');
					inptValue = $fld.val();
				}else{
					$fld = $container.find('select:eq(0)');
					inptValue = $fld.val();
					if(inptValue == '0') inptValue = '';
				}
				break;
			case 'choice':
				$fld = $container.find('select:eq(0)');
				inptValue = $fld.val();
				break;
			case 'plain':
				$fld = $container.find('textarea:eq(0)');
				inptValue = $fld.val();
				break;
			case 'link':
			case 'pic':
				$fld = $container.find('input:eq(0)');
				inptValue = $fld.val();
				if(inptValue.indexOf('http://') > -1) inptValue = inptValue.substring(inptValue.indexOf('http://') + 7);
				else if(inptValue.indexOf('https://') > -1) inptValue = inptValue.substring(inptValue.indexOf('https://') + 8);
				break;
			case 'text':
			case 'num':
			case 'date':
			case 'datetime':
			case 'percent':
			default:
				$fld = $container.find('input:eq(0)');
				inptValue = $fld.val();
				break;
		}

	    if(inptValue == ''){
	      pass = false;
	      if($container.find('.ms-formvalidation').length == 0)
	        $container.append($("<div class='ms-formvalidation'>" + emptyCaution + "</div>"));
	      $fld.focus();
	    }else{
			$container.find('.ms-formvalidation').remove();
		}	
	}
  });
  return pass;
}

/*
 * clear the empty check
 * fields: field dictionary
 * unCheckFields: fields to remove check
 */
function clearCheckEmptyFields(fields, unCheckFields){
  $.each(unCheckFields, function(idx, fldName){
    $(fields[fldName]).find('.ms-formlabel nobr').empty().text(fldName);
  });
  clearCustomSave();
}

/*
 * initialize to check empty fields
 * fields: field dictionary
 * checkFields: fields to check
 * fldTypes: types of the fields
 * emptyCaution: when empty, the caution text to display
 * preFunc: custom function before save (after field check)
 * saveFunc: custom save function (after field check), null or undefined to use the default save action
 */
function initCheckEmptyFields(fields, checkFields, fldTypes, emptyCaution, preFunc, saveFunc){
  // validation star
  $.each(checkFields, function(idx, fldName){
    var $td = $(fields[fldName]).find('.ms-formlabel');
    if($td.find('.ms-formvalidation').length == 0)
      $td.find('nobr').append("<span class='ms-formvalidation'>&nbsp;*</span>");
  });

  // button
  redefineSave(function(){
	  	if(preFunc != undefined && preFunc != null) preFunc();
        if(checkEmpty(fields, checkFields, fldTypes, emptyCaution)){
			if(saveFunc != undefined && saveFunc != null) saveFunc();
			else $('.ms-ButtonHeightWidth[id$="SaveItem"]:eq(0)').click();
		}
  });
}

/*
 * redefine the action of the save button
 * customFunc: function of the custom action
 * customText: text of the new button
 */
function redefineSave(customFunc, customText){
	$('.ms-ButtonHeightWidth[id$="SaveItem"]').each(function(){
	    $(this).hide();
		if(customText == undefined || customText == null) customText = $(this).val();
		$("<input type='button' value='" + customText + "' class='ms-ButtonHeightWidth' name='dummySave'/>")
		      .click(function(){
	  			if(customFunc != undefined && customFunc != null) customFunc();
		      })
		.insertBefore($(this));
  });
}

/*
 * clear the custom save action, use the default
 */
function clearCustomSave(){
    $('.ms-ButtonHeightWidth[name="dummySave"]').remove();
	$('.ms-ButtonHeightWidth[id$="SaveItem"]').show();
}

/*
 * redefine the action of the cancel button
 * customFunc: function of the custom action
 * customText: text of the new button
 */
function redefineCancel(customFunc, customText){
	$('.ms-ButtonHeightWidth[id$="GoBack"]').each(function(){
	    $(this).hide();
		if(customText == undefined || customText == null) customText = $(this).val();
		$("<input type='button' value='" + customText + "' class='ms-ButtonHeightWidth' name='dummyCancel'/>")
		  .click(function(){
			if(customFunc != undefined && customFunc != null) customFunc();
		  })
		  .insertBefore($(this));
  });
}
/*
 * clear the custom cancel action, use the default
 */
function clearCustomCancel(){
    $('.ms-ButtonHeightWidth[name="dummyCancel"]').remove();
	$('.ms-ButtonHeightWidth[id$="GoBack"]').show();
}

/*
 * get url queries
 * return: url queries dictionary
 */
function getUrlQueries(){
	var srch = window.location.search;
	if(srch.length > 0) srch = srch.substring(1);
	var sep = srch.split('&');
	var queries = {};
	$.each(sep, function(idx, part){
	  var tmp = part.split('=');
	  queries[tmp[0]] = decodeURIComponent(tmp[1]);
	});
	return queries;
}

/*
 * go to url which in the ?Source= url query
 * defaultTarget: if the source is null, where to go
 */
function goToSource(defaultTarget){
  var queries = getUrlQueries();
  if(queries['Source'] == undefined){
    if(defaultTarget != undefined) window.location = defaultTarget;
  }else window.location = queries['Source'];
}
