/**************************************************************************
* 커스텀 태그로 Class인스턴스 생성 및 설정
**************************************************************************/
function registBaseObject(pageName){
	
	let xmlElements = new DomQuery().setContainers("[data-doctx='"+pageName+"']").findAll("[data-xml-conf]");
	
	let pageObjectDeclarationEnd = false;
	let confDeclarationEnd = false;
	
	
	let allScript = "";
	for(let xmlElement of xmlElements){
		
		var isGlobalObject = true;
		if(xmlElement.hasAttribute("is-not-global")){
			isGlobalObject = false;
		}
		
		let pageObject_abbreviation_s = "";
		if(!isGlobalObject && !pageObjectDeclarationEnd){
			pageObject_abbreviation_s = "var $P = pageObject."+pageName+";";
		}
		
		let baseObject = xmlElement.dataset.name;
		let baseObjectType = xmlElement.className;
		
		let scriptForSingleObject = "";
		
		let createInstance_s = "";
		if(xmlElement.querySelector("new-function") == null && xmlElement.querySelector("new-constructor") == null){
			continue;
		}

		let newConf = xmlElement.querySelector("new-function") 
		? xmlElement.querySelector("new-function") 
		: xmlElement.querySelector("new-constructor");

		let leftOfNew = "var ";
		if(!isGlobalObject){
			leftOfNew = "$P.";
		}
		
		if(newConf.tagName == "NEW-FUNCTION"){
			// 사용자정의함수로 인스턴스 생성
			createInstance_s = leftOfNew + baseObject + " = "+newConf.textContent +";";
		} else if(newConf.tagName == "NEW-CONSTRUCTOR"){
			//new 생성자로 인스턴스 생성
			//conf argument 설정 스크립트
			var confDeclaration = "";
			if(!confDeclarationEnd){
				confDeclaration = "var "
			}
			
			let conf_s = confDeclaration+"conf = " + newConf.textContent +";";
			//인스턴스생성스크립트
			let newContructor_s = leftOfNew + baseObject + " = new "+baseObjectType+"(conf);";
			createInstance_s = conf_s + "\n" + newContructor_s;
		}
		
		let instanceNameDef_s = "";
		if(!isGlobalObject){
			instanceNameDef_s = "var "+baseObject+" = $P."+baseObject+";";
		} else {
			instanceNameDef_s = "window."+baseObject+" = "+baseObject+";";
		}
		
		if(xmlElement.tagName == "DATASETCONTROL-C"){
			//컨트롤인스턴스명		
			const overwritableMehtods = [
				"onDatasetChange",
				"onCurrentChange",
				"onSelectionChange",
				"onModify",
				"onAppend",
				"onSort",
				"onReplace",
				"onSave",
				"onRemove",			
				"save",
				"remove",
				"getInfo",
				"setInfo"
			];
			//메소드 재정의
			let methodOverwrite_s = "";
			for(var i=0; i < xmlElement.children.length; i++){
				let methodDef = xmlElement.children[i];
				if(overwritableMehtods.indexOf(methodDef.className) != -1){
					methodOverwrite_s += overwriteMethodScript(baseObject, methodDef.className, methodDef);
				}
			}
			
			scriptForSingleObject = pageObject_abbreviation_s + "\n"
						+ createInstance_s + "\n"
						+ instanceNameDef_s + "\n"
						+ methodOverwrite_s + "\n";
		} else {
			scriptForSingleObject = pageObject_abbreviation_s + "\n"
						+ createInstance_s + "\n"
						+ instanceNameDef_s + "\n";
						
		}

		
		allScript += scriptForSingleObject + "\n";

		
		if(!isGlobalObject){
			pageObjectDeclarationEnd = true;
		}
		if(newConf.tagName == "NEW-CONSTRUCTOR"){
			confDeclarationEnd = true;
		}
	}
	
	let register = document.createElement("script");
	register.innerHTML = "(function(){" + "\n"
				+ allScript
				+ "})();"
								
	document.body.appendChild(register);
	document.body.removeChild(register);
}

function overwriteMethodScript(baseObject, m_name, methodDef){
	let result_script = "";
	if(methodDef != null && methodDef.textContent.trim() != ""){
		let hasOnObj = "";
		if(methodDef.hasAttribute("is-not-control")){
			hasOnObj = ".dataset";
		}
		
		if(methodDef.textContent.trim() != "null"){
			result_script = baseObject+hasOnObj+"."+m_name+" = " + methodDef.textContent+";"+"\n";
		} else {
			result_script = baseObject+hasOnObj+"."+m_name+" = () => {};"+"\n";
		}
	}
	return result_script;
}


/**************************************************************************
* 커스텀 태그(클래스)
**************************************************************************/
class XmlDatasetControl extends HTMLElement {
	constructor() {
		super();
		this.setAttribute("data-xml-conf","");
		this.className = "DatasetControl";
		this.setAttribute("hidden","hidden");
	}
}
customElements.define("datasetcontrol-c", XmlDatasetControl);

class XmlPagingSupport extends HTMLElement {
	constructor() {
		super();
		this.setAttribute("data-xml-conf","");
		this.className = "PagingSupport";
		this.setAttribute("hidden","hidden");
	}
}
customElements.define("pagingsupport-c", XmlPagingSupport);

class XmlTableSupport extends HTMLElement {
	constructor() {
		super();
		this.setAttribute("data-xml-conf","");
		this.className = "TableSupport";
		this.setAttribute("hidden","hidden");
	}
}
customElements.define("tablesupport-c", XmlTableSupport);

class XmlFormFields extends HTMLElement {
	constructor() {
		super();
		this.setAttribute("data-xml-conf","");
		this.className = "FormFields";
		this.setAttribute("hidden","hidden");
	}
}
customElements.define("formfields-c", XmlFormFields);

/**************************************************************************
* 커스텀 태그(생성자)
**************************************************************************/
class XmlNewFunction extends HTMLElement {
	constructor() {
		super();
	}
}
customElements.define("new-function", XmlNewFunction);

class XmlNewConstructor extends HTMLElement {
	constructor() {
		super();
	}
}
customElements.define("new-constructor", XmlNewConstructor);

/**************************************************************************
* 커스텀 태그(class메소드)
**************************************************************************/
class XmlOnDatasetChange extends HTMLElement {
	constructor() {
		super();
		this.className = "onDatasetChange";
	}
}
customElements.define("ondatasetchange-f", XmlOnDatasetChange);

class XmlOnCurrentChange extends HTMLElement {
	constructor() {
		super();
		this.className = "onCurrentChange";
	}
}
customElements.define("oncurrentchange-f", XmlOnCurrentChange);

class XmlOnSelectionChange extends HTMLElement {
	constructor() {
		super();
		this.className = "onSelectionChange";
	}
}
customElements.define("onselectionchange-f", XmlOnSelectionChange);

class XmlOnModify extends HTMLElement {
	constructor() {
		super();
		this.className = "onModify";
	}
}
customElements.define("onmodify-f", XmlOnModify);

class XmlOnAppend extends HTMLElement {
	constructor() {
		super();
		this.className = "onAppend";
	}
}
customElements.define("onappend-f", XmlOnAppend);

class XmlOnSort extends HTMLElement {
	constructor() {
		super();
		this.className = "onSort";
	}
}
customElements.define("onsort-f", XmlOnSort);

class XmlOnReplace extends HTMLElement {
	constructor() {
		super();
		this.className = "onReplace";
	}
}
customElements.define("onreplace-f", XmlOnReplace);

class XmlOnSave extends HTMLElement {
	constructor() {
		super();
		this.className = "onSave";
	}
}
customElements.define("onsave-f", XmlOnSave);

class XmlOnRemove extends HTMLElement {
	constructor() {
		super();
		this.className = "onRemove";
	}
}
customElements.define("onremove-f", XmlOnRemove);

class XmlSave extends HTMLElement {
	constructor() {
		super();
		this.className = "save";
	}
}
customElements.define("save-f", XmlSave);

class XmlRemove extends HTMLElement {
	constructor() {
		super();
		this.className = "remove";
	}
}
customElements.define("remove-f", XmlRemove);

class XmlGetInfo extends HTMLElement {
	constructor() {
		super();
		this.className = "getInfo";
	}
}
customElements.define("getinfo-f", XmlGetInfo);

class XmlSetInfo extends HTMLElement {
	constructor() {
		super();
		this.className = "setInfo";
	}
}
customElements.define("setinfo-f", XmlSetInfo);
