function ckCommonEditObj() {
	this.varName=(arguments.length==1 ? arguments[0] : "commonEdit");
	this.fwDefaultWidth = 500;
	this.fieldPrefix = this.varName +".";
	
	//these can be forced to non-default values by setting in individual object inits
	this.listContainerID = this.varName + ".tab.content"; //default to view on own tab.
	this.viewContainerID = this.varName + ".tab.content"; //default to view on own tab.
	this.editContainerID = "floatingWindow." + this.varName; //default to edit in floating window
	
	this.fnCustomReturnHandler_list = null;
	this.aParams = Array(); //Should be used to set data that always gets sent...except if saving FORM object
	
	this.getURL = "";
	this.saveURL = "";
	this.editURL = "";
	this.viewURL = "";
	this.listURL = "";
	this.deleteURL = "";
	this.saveSortOrderURL = "";
	
	this.lastActionCode="";
	this.bDirty = false;
	this.bSaveAndAdd = false;
	
	return this;
}

/*----- Save --------------------------------------------------------------------------------------------*/

ckCommonEditObj.prototype.save=function() {
	var bAutoValidate = (arguments.length >= 1 ? arguments[0] : true);
	var variant = (arguments.length >= 2 ? arguments[1] : this.varName + ".field"); //some edit objects like galleryEditObj have multiple save types (image,group,gallery). This could be the name attribute or a FORM object
	var bShowWait = (arguments.length == 3 ? arguments[2] : true);
	if (bAutoValidate) oError.autoValidate(variant); //param allows custom handling and just use superClass for submission
	if (!oError.anyErrors()) {
		oFloatingWindow.hideErrWarnSuccess();
		
		if (typeof(variant)=="object") {
			if (variant.actionCode) this.lastActionCode = variant.actionCode.value;
			(new ckAjaxObj()).postForm(variant,this.ajaxReturnHandler_save,this);
			
		} else {	
			var oEl = this.getElement("actionCode");
			if (oEl) this.lastActionCode = oEl.value;
			
			var sURL = this.saveURL; //so we're not modifying the global URL and constantly appending
			var sParams = this.getParams();
			if (sParams != "") sURL += "?" + sParams;
			(new ckAjaxObj()).postFormDataByName(sURL,variant,this.ajaxReturnHandler_save,this);
		}
		
		if (bShowWait) oFloatingWindow.showWait();
	}
}
ckCommonEditObj.prototype.ajaxReturnHandler_save = function(oAjax) {
	var oResponse = oAjax.responseObj;
	
	if (!oResponse) oFloatingWindow.showError(oAjax.responseText);
	else {
		this.setDirty(false);
		oFloatingWindow.hide();
		if (oResponse.payload.successMsg) oStdContainer.displaySuccess(oResponse.payload.successMsg);
		if (oResponse.payload.warningMsg) oStdContainer.displayWarning(oResponse.payload.warningMsg);

		if (!oResponse.payload.oContentUpdates) this.list();  //anything edited in a "properties" page format (article,subscriptions) will not want to list after save
		
		if (this.bSaveAndAdd) {
			this.create();
			this.bSaveAndAdd = false;
		}
	}
}
ckCommonEditObj.prototype.saveAndAdd=function() {
	//doesn't pass through optional parameters.  Will call save and create with all default options
	this.bSaveAndAdd = true;
	this.save();
}
/*----- List --------------------------------------------------------------------------------------------*/

ckCommonEditObj.prototype.list = function() {
	var sData = (arguments.length >= 1 ? arguments[0] : "");
	var oAjax = (arguments.length >= 2 ? arguments[1] : new ckAjaxObj()); //so we can pass in an ajax object with special settings (like errorDisplayID)


	oAjax.postFormData(this.listURL,this.getParams(sData),this.ajaxReturnHandler_list,this);
}
ckCommonEditObj.prototype.ajaxReturnHandler_list = function(oAjax) {
	//this handler is never overwritten so we can always revert to default handler by passing in null value for the custom return handler. 
	if (this.fnCustomReturnHandler_list) this.fnCustomReturnHandler_list.call(this,oAjax);
	else {
		this.fillContainer(document.getElementById(this.listContainerID),oAjax.responseText);
		oAjax.executeScripts();
	}
}
ckCommonEditObj.prototype.showListContainerWait = function() {
	this.showContainerWait(this.listContainerID,(arguments.length==1 ? arguments[0] : "Retrieving list..."));
}
ckCommonEditObj.prototype.paginate = function() {
	var page = (arguments.length >= 1 ? arguments[0] : 1);
	var pageSize = (arguments.length >= 2 ? arguments[1] : 25);
	
	this.setParam("page",page)
	this.setParam("pageSize",pageSize);
	this.list(); //not all functions have same optional parameter config for list, so can't pass anything into it  //this.list({'pageSize':pageSize,'page':page});	
}

/*----- Sort Order --------------------------------------------------------------------------------------*/

ckCommonEditObj.prototype.saveSortOrder= function() {
	oFloatingWindow.showWait();
	oStdContainer.clearAll();
	var sData = (arguments.length >= 1 ? arguments[0] : "");
	var sActionCode = (arguments.length >= 2 ? arguments[1] : "saveOrder"); //in case multiple orders in single action page
	var sOrderedIDs = (arguments.length == 3 ? arguments[2] : oTableRowSort.getOrderedIDs());
	sData += (sData != "" ? "&" : "") + "actionCode=" + sActionCode + "&orderedIDs=" + sOrderedIDs;
	(new ckAjaxObj()).postFormData(this.saveSortOrderURL,this.getParams(sData),this.ajaxReturnHandler_saveSortOrder,this);
}
ckCommonEditObj.prototype.ajaxReturnHandler_saveSortOrder= function(oAjax) {
	if (!oAjax.responseObj) oFloatingWindow.showError(oAjax.responseText);
	else {
		this.setSortOrderMessage("The sort order has been saved")
		oFloatingWindow.hideWait();
	}
}
ckCommonEditObj.prototype.clearSortOrderMessage = function() { this.setSortOrderMessage(''); }
ckCommonEditObj.prototype.setSortOrderMessage = function(sMsg) { this.fillContainer(document.getElementById(this.varName + ".sortOrder.message"),sMsg); }

/*----- Edit ---------------------------------------------------------------------------*/

ckCommonEditObj.prototype.create=function() { this.edit(''); }
ckCommonEditObj.prototype.edit = function() {
	var sData = (arguments.length >=1 ? arguments[0] : ""); //not every call will have data to send
	var sTitle = (arguments.length >= 2 ? arguments[1] : "");
	var oEl;
	if (oEl = oFloatingWindow.getOrCreate(this.editContainerID,this.fwDefaultWidth,sTitle)) {
		oFloatingWindow.showAndWait(this.editContainerID);
		(new ckAjaxObj()).postFormData(this.editURL,this.getParams(sData),this.ajaxReturnHandler_edit,this);
	}
}
ckCommonEditObj.prototype.ajaxReturnHandler_edit = function(oAjax) {
	if (oFloatingWindow.fillAndShow(this.editContainerID,oAjax.responseText)) {
		oAjax.executeScripts();
		
		oFloatingWindow.refreshDisplay();//scripts could show/hide elements that require resizing window
		oValidation.markRequiredFields();
		this.onEditActions(); //allow object that inherit ckCommonEdit to implement so they can still always use this as the default return handler call.
	}
}

ckCommonEditObj.prototype.onEditActions = function() { }


/*--------------------------------------------------------------------------------
Delete
--------------------------------------------------------------------------------*/
ckCommonEditObj.prototype.deleteData = function(sData) {
	var sDeleteText = (arguments.length>=2 ? arguments[1] : "");
	var bCustomPhrase = (arguments.length >=3 ? arguments[2] : false);
	if (sDeleteText !="") {
		var sDeletePhrase = (bCustomPhrase ? sDeleteText : "Are you sure you want to delete this " + sDeleteText + "?");

		if (oFloatingWindow.confirm(sDeletePhrase,this)) {
			(new ckAjaxObj()).postFormData(this.deleteURL,this.getParams(sData),this.ajaxReturnHandler_delete,this);
		}
	} else {
		(new ckAjaxObj()).postFormData(this.deleteURL,this.getParams(sData),this.ajaxReturnHandler_delete,this);
	}
}
ckCommonEditObj.prototype.ajaxReturnHandler_delete = function(oAjax) {
	var oEl;
	var oResponse = oAjax.responseObj;
	
	if (!oResponse) oFloatingWindow.showError(oAjax.responseText);
	else {
		oFloatingWindow.hide();
		if (oResponse.payload.successMsg) oStdContainer.displaySuccess(oResponse.payload.successMsg);
		if (oResponse.payload.warningMsg) oStdContainer.displayWarning(oResponse.payload.warningMsg);
		
		if (oResponse.payload.deletedID != null) { 
			if (oEl = document.getElementById(this.varName + "." + oResponse.payload.deletedID)) {

				var oTable, oRow;
				var bAlternateColors = (oEl.className.toLowerCase()=="tablerow1" || oEl.className.toLowerCase()=="tablerow2");
				var bReformatted = false;
				
				if (oEl.tagName=="TR") oTable = oDHTML.seekParentTag(oEl,"TABLE");
				
				oEl.parentNode.removeChild(oEl); 
				
				if (oTable && bAlternateColors) {
					try {
						if ((oTableRowSort) && (oTableRowSort.oTable == oTable)) { //oTableRowSort may be present, but may not be active on the table on the page we're deleting from
							oTableRowSort.reformatTable(); //handles sort buttons
							bReformatted=true;
						}
					} catch(err) { 
						//oTableRowSort may not be defined on page
					}
					
					if(!bReformatted) {
						var rowIndex = 0;
						var rowCount = oTable.rows.length;
						for (var index=0; index < rowCount; index++) if ((oRow = oTable.rows.item(index)) && (oRow.style.display != "none")) oRow.className=(++rowIndex % 2==0 ? "tablerow1" : "tableRow2");
					}
				}
				
				return;
			}
		}
		this.list();
	}
}
/*--------------------------------------------------------------------------------
Get
--------------------------------------------------------------------------------*/
ckCommonEditObj.prototype.get = function() {
	//does not automatically show a floating window to show data in. Could be used to get data to show in a tab or other container. Use .view() to open in a floatingWindow
	var sData = (arguments.length==1 ? arguments[0] : "");
	(new ckAjaxObj()).postFormData(this.getURL,this.getParams(sData),this.ajaxReturnHandler_get,this);
}
ckCommonEditObj.prototype.ajaxReturnHandler_get = function(oAjax) {
	this.fillContainer(document.getElementById(this.viewContainerID),oAjax.responseText);
	oAjax.executeScripts();
	try {
		if (oFloatingWindow.isShowing()) oFloatingWindow.refreshDisplay();//scripts could show/hide elements that require resizing window
	} catch (err) {}
}
ckCommonEditObj.prototype.showViewContainerWait = function() {
	this.showContainerWait(this.viewContainerID,(arguments.length==1 ? arguments[0] : "Retrieving..."));
}
/*--------------------------------------------------------------------------------
View
--------------------------------------------------------------------------------*/
ckCommonEditObj.prototype.view = function(sData) {
	var sTitle = (arguments.length==2 ? arguments[1] : "");
	var oEl;
	if (oEl = oFloatingWindow.getOrCreate(this.viewContainerID,this.fwDefaultWidth,sTitle)) {
		oFloatingWindow.showAndWait(this.viewContainerID);
		(new ckAjaxObj()).postFormData(this.viewURL,this.getParams(sData),this.ajaxReturnHandler_view,this);
	}
}
ckCommonEditObj.prototype.ajaxReturnHandler_view = function(oAjax) {
	if (oFloatingWindow.fillAndShow(this.viewContainerID,oAjax.responseText)) {
		oAjax.executeScripts();
		oFloatingWindow.refreshDisplay();//scripts could show/hide elements that require resizing window
	}
}

/*--------------------------------------------------------------------------------
Utilities
--------------------------------------------------------------------------------*/
ckCommonEditObj.prototype.showContainerWait = function(containerID) {
	var sMsg = (arguments.length >= 2 ? arguments[1] : "Retrieving...");
	var bReplaceContent = (arguments.length >= 3 ? arguments[2] : true); //by default, wait content replaces all other content in container.

	var oEl = document.getElementById(containerID);
	if (oEl) {
		if (bReplaceContent) oEl.innerHTML = "";
	
		if (!document.getElementById(containerID + ".status")) { 
			//to avoid messing up any classes placed on outer container, a separate div is created within with the ".status" extension
			//	since that is the default displayID for certain ajax call errors.
			var oDiv = document.createElement("DIV");
			oDiv.id = containerID + ".status";
			
			oEl.insertAdjacentElement("afterBegin",oDiv);
		}
		if (oEl = document.getElementById(containerID + ".status")) {
			this.fillContainer(oEl,'<div class="waitingDisplay">' + sMsg + '</div>');
			oEl.style.display="block";
		}
	}
}

ckCommonEditObj.prototype.setReturnHandler_save=function(fnPtr) {
	if (!fnPtr) this.ajaxReturnHandler_save=null; //no return desired
	else this.ajaxReturnHandler_save = fnPtr; 
}
ckCommonEditObj.prototype.setReturnHandler_delete=function(fnPtr) {
	if (!fnPtr) this.ajaxReturnHandler_delete=null; //no return desired
	else this.ajaxReturnHandler_delete = fnPtr;
}
ckCommonEditObj.prototype.setReturnHandler_list=function(fnPtr) {
	if (!fnPtr) this.fnCustomReturnHandler_list=null; //revert to default
	else this.fnCustomReturnHandler_list = fnPtr;
}

ckCommonEditObj.prototype.getElement=function(sName) {
	return(document.getElementById(this.fieldPrefix + sName));
}
ckCommonEditObj.prototype.getContainer=function(sID) {
	//floating window is assumed, so automatically create container if not found
	var oDiv = document.getElementById(sID);
	if (!oDiv) {
		var width = (arguments.length==2 ? arguments[1] : this.fwDefaultWidth);
		
		oDiv = document.createElement("DIV");
		oDiv.id = sID
		oDiv.style.width = width + "px";
		oDiv.style.display = "none";
		oDiv = document.body.appendChild(oDiv);
	}
	return oDiv;
}
ckCommonEditObj.prototype.showAndWait=function(containerID,sTitle) {
	//floatingWindow assumed for this call
	oFloatingWindow.addContentType(containerID,sTitle,this.getContainer(containerID)); 
	oFloatingWindow.showAndWait(containerID);
}
ckCommonEditObj.prototype.fillContainer=function(oEl,sHTML) {
	if (oEl) {
		oEl.innerHTML = sHTML;
		return true;
	} else {
		throwConsoleError("ckCommonEditObj.fillContainer()","Container is null");
		return false;
	}
}
ckCommonEditObj.prototype.setParam= function(sName,sValue) {
	this.aParams[sName] = sValue;
}
ckCommonEditObj.prototype.getParams = function() { 
	//should always be called when sending data since it takes aParams into consideration
	var sParams = (arguments.length==1 ? arguments[0]+"" : "");
	//anything passed directly as a parameter should override the same parameter in aParams

	var aData = sParams.split("&");
	for (var index=0; index < aData.length;index++) {
		var aTemp = aData[index].split("=");

		if (this.aParams[aTemp[0]] != null) { //important to do null check since an empty string value (which is a valid value) would return false
			this.setParam(aTemp[0],aTemp[1]);
			aData[index] = null; //clear so not added twice
		}
		if (aTemp[0] == "actionCode") this.lastActionCode=aTemp[1]; //sometimes useful to know what actionCode was called last for objects that have one returnHandler for different calls
	}

	sParams = "";
	for (var index=0; index < aData.length;index++) if (aData[index] != null) sParams += (sParams != "" ? "&" : "") + aData[index];

	for (var key in this.aParams) if (this.aParams[key] != null) sParams += (sParams != "" ? "&" : "") + key + "=" + this.aParams[key];

	if (sParams != "") sParams = getURIEncoded(sParams); //encoding a blank string returns " =undefined"	

	return sParams;
}
ckCommonEditObj.prototype.setDirty= function() {
	this.bDirty = (arguments.length==1 ? arguments[0] : true);
}

ckCommonEditObj.prototype.disableAllElements = function() {
	var bDisable = (arguments.length >= 1 ? arguments[0] : true);
	var variant = (arguments.length >=2 ? arguments[1] : this.varName + ".field"); //allow passing in a FORM object instead of using getElementsByName

	var oEl;
	var oData = formObjectsArray(variant);
	for (var sFieldName in oData)  {
		if (oData[sFieldName]) {
			for (var index=0; index < oData[sFieldName].aEl.length; index++) {
				oEl = oData[sFieldName].aEl[index];
				if ((oEl) && (oEl.type != "hidden")) oEl.disabled = bDisable;
			}
		}
	}
}
/*--------------------------------------------------------------------------------

UNCOFIRMED BELOW HERE

--------------------------------------------------------------------------------*/


ckCommonEditObj.prototype.getFormValue=function(sName) {
	var oEl;
	var sValue = "";
	
	if (oEl = this.getElement(sName)) {
		switch (oEl.type) {
			case "checkbox":
				sValue = (oEl.checked ? oEl.value : "");
				break;
			case "radio" :
				//if "radioDisplay" is used, all radios for a field are going to have the same name and id attributes
				var aFields = document.getElementsByName(this.fieldPrefix + sName);
				for (var index=0; index < aFields.length; index++) {
					if (aFields[index].checked) sValue=aFields[index].value;
				}
				break;
			default :
				sValue = oEl.value;
		}
	}
		
	return sValue;
}


