/**
 * @file 공통 처리용 유틸성 기능을 제공한다.
 * 공통 코드 호출 및 컴포넌트 연동, 통신 메세지 처리 등
 * @version 2.0
 * @author InswaveSystems
 *
 */

/**
 * 공통 처리용 유틸성 기능을 제공한다.
 * @type eduCommon
 * @class eduCommon
 * @namespace eduCommon
 */
var eduCommon = {
	CONTEXT_PATH : "/boerp", // Context Path 경로
	DEFAULT_OPTIONS_MODE : "asynchronous", // 기본 통신 모드 ( asynchronous / synchronous)
	DEFAULT_OPTIONS_MEDIATYPE : "application/json", // 기본 미디어 타입
	MESSAGE_CODE : {
		STATUS_ERROR : "E",
		STATUS_SUCCESS : "S",
		STATUS_WARNING : "W"
	},
	commonCodeInfo : {
		idPrefix:"dlt_CommonCode",
		label:"code_nm",
		value:"code_cd",
		fieldArr : ["grp_cd","code_cd","code_nm"]
	},
	/**
	 * config.xml에서 사용 visibleHelper로 엔진에서 사용. 단독 사용 금지.
	 * @private
	 * @date 2017. 3. 7.
	 * @memberOf eduCommon
	 * @author InswaveSystems
	 */
	_setWebSquareContent : function(htmlStr){
		var contBox = document.getElementById("wsContent") || document.body;
		contBox.innerHTML = htmlStr;
	},
	/**
	 * 총 행의 수와 화면에 보여질 행의 수를 가지고 페이지수를 반환한다.
	 * @date 2017. 3. 7.
	 * @param {Number} totalRowCount 총 행의 수
	 * @param {Number} rowCount 화면에 보여지는 행의 수
	 * @returns {Number} pageCount
	 * @memberOf eduCommon
	 * @author InswaveSystems
	 * @example
	 * var rs = eduCommon.getPageSize(100,10);
	 * //return 예시) 10
	 * var rs2 = eduCommon.getPageSize(101,10);
	 * //return 예시) 11
	 */
	getPageSize : function(totalRowCount, rowCount){
		return Math.ceil(totalRowCount/rowCount);
	},
	/**
	 * eduCommon에 정의된 CONTEXT_PATH를 포함한 URL을 반환한다.
	 * @date 2017. 3. 20.
	 * @param {String} url URL경로
	 * @returns {String} CONTEXT가 포함된 URL경로
	 * @memberOf eduCommon
	 * @author InswaveSystems
	 * @example
	 * //아래와 같이 CONTEXT가 정의된 경우
	 * eduCommon.CONTEXT_PATH = "ws5";
	 * var rs = eduCommon.getURL("/ws/sample.xml");
	 * //return 예시) "/ws5/ws/sample.xml"
	 * var rs2 = eduCommon.getURL("/edu/selectMember.do");
	 * //return 예시) "/ws5/edu/selectMember.do"
	 * var rs3 = eduCommon.getURL("/ws5/edu/selectMember.do");
	 * //return 예시) "/ws5/edu/selectMember.do"
	 */
	getURL : function(url){
		var tmpPath = url.charAt(0) === "/" ? this.CONTEXT_PATH : this.CONTEXT_PATH +"/";

		if(url.startsWith( tmpPath+"/" ) || url.startsWith( "." )){
			return url;
		}else{
			return tmpPath+url;
		}
	}
};


/**
 * 코드성 데이터와 컴포넌트의 nodeSet(아이템 리스트)연동 기능을 제공한다.
 * code별로 JSON객체를 생성하여 array에 담아 첫번째 파라메터로 넘겨준다.
 * 그리드뷰의 경우 compID는 [컴포넌트아이디]:[컬럼명]으로 작성한다.
 * @date 2016. 07. 27.
 * @param {JSON} codeJsonArr {"code" : "코드넘버", "compID" : "적용할 컴포넌트명"}
 * @param {String} callbackFuncStr 콜백 함수명
 * @memberOf eduCommon
 * @author InswaveSystems
 * @example
 * eduCommon.setCommonCode([
 * 		{"code:":"04","compID":"sbx_CommCodeReligion"},
 * 		{"code:":"24","compID":"grd_CommCodeSample:JOB_CD"}
 * 		], "setCommonCodeCallback");
 */
eduCommon.setCommonCode = function(codeJsonArr, callbackFuncStr, codeStatus){
	var codeJsonArrLen;
	if(codeJsonArr){
		 codeJsonArrLen = codeJsonArr.length;
	}else{
		$w.log("=== eduCommon.setCommonCode Parameter Type Error ===\nex) eduCommon.setCommonCode([{\"code:\":\"04\",\"compID\":\"sbx_Gender\"}],\"edu.callbackFunction\")\n===================================");
		return;
	}

	var i, j, codeObj, dltId, dltIdArr=[], paramCode = "", compArr, compArrLen, tmpIdArr, cstatus;
	var commCodeInfo = eduCommon.commonCodeInfo;
	var dataPrefix = commCodeInfo.idPrefix;

	var dcFormObj = eduCommon.getCodeDCForm(commCodeInfo.fieldArr);
	for(i=0;i<codeJsonArrLen;i++){
		codeObj = codeJsonArr[i];
		try{
			if(i>0){
				paramCode += ",";
			}
			dltId = dataPrefix+codeObj.code;
			dltIdArr.push(dltId);
			paramCode += codeObj.code;

			dcFormObj.id = dltId;

			try{
				$w.data.remove(dltId);
			}catch(ex){}

			$w.data.create(dcFormObj);

			if(codeObj.compID){	//컴포넌트의 ID가 없는 경우도 있음.
				compArr = (codeObj.compID).replaceAll(" ","").split(",");
				compArrLen = compArr.length;
				for(j=0;j<compArrLen;j++){
					tmpIdArr = compArr[j].split(":");
					try{
						if(tmpIdArr.length === 1){	//기본 컴포넌트
							window[tmpIdArr[0]].setNodeSet("data:"+dltId, commCodeInfo.label, commCodeInfo.value);
						}else{	//gridView 컴포넌트
							window[tmpIdArr[0]].setColumnNodeSet(tmpIdArr[1], "data:"+dltId, commCodeInfo.label, commCodeInfo.value);
						}
					}catch(ex){
						$w.log(tmpIdArr[0] + "이 존재하지 않습니다.");
					}
				}
			}

		}catch(ex){
			$w.log("eduCommon.setCommonCode Error");
			$w.log(JSON.stringify(codeObj));
			//$w.log(ex);
			continue;
		}
	}

	// submission 생성
    var searchCodeGrpOption = {
    	id : "sbm_SearchCode",
    	action : "/getCodeList",
    	target : "data:json," + JSON.stringify(dltIdArr),
    	isShowMeg : false };

    if(callbackFuncStr){
    	searchCodeGrpOption.submitDoneHandler = callbackFuncStr;
    }

    eduCommon.executeSubmission_dynamic(searchCodeGrpOption,{"dma_Common_Code":{"GRP_CD" : paramCode, "DATA_PREFIX" : dataPrefix , "STATUS" : codeStatus}});
};

/**
 * 공통 코드용 dataList의 골격을 생성하여 반환한다.
 * setCommonCode에서 사용.
 * @private
 * @date 2016. 11. 15.
 * @param {JSON} idStr 생성할 DataList ID
 * @memberOf eduCommon
 * @author InswaveSystems
 */

eduCommon.getCodeDCForm = function(infoArr){
	var option = {
		"type" : "dataList",
		"option":{ "baseNode": "list", "repeatNode": "map"},
		"columnInfo":[]
    };
	//{"id":"GRP_CD", "name":"코드그룹", "dataType":"text"}
	var i, infoArrLen;
	infoArrLen = infoArr.length;

	for(i=0;i<infoArrLen;i++){
		//option.columnInfo.push({"id":"GRP_CD", "name":"코드그룹", "dataType":"text"});
		option.columnInfo.push({"id":infoArr[i]});
	}

	return option;
};

/**
 * submission를 실행한다.
 * submission의 id로 객체가 존재하지 않으면 생성후 실행한다.
 *
 * @date 2014. 12. 9.
 * @private
 * @param {JSON} options createSubmission의 options 참고
 * @param {JSON} requestData 요청 데이터
 * @param {JSON} obj 전송중 disable시킬 컴퍼넌트
 * @memberOf eduCommon
 * @author InswaveSystems
 * @example
 * var searchCodeGrpOption = {
 * 		id : "sbm_SearchCodeGrp"
 * 		,action : "serviceId=CD0001&action=R"
 * 		,target : 'data:json,{"id":"dlt_CodeGrp","key":"data"}'
 * 		,submitDoneHandler : "searchCodeGrpCallback", isShowMeg : false };
 * executeSubmission_dynamic(searchCodeGrpOption);
 */
eduCommon.executeSubmission_dynamic = function(options, requestData , obj) {
    var submissionObj = $w.getSubmission(options.id);
    if (submissionObj === null) {
        eduCommon.createSubmission(options);
    } else {
       eduCommon.setSubmission(submissionObj, options);
    }

    $w.executeSubmission( options.id, requestData, obj);
};


/**
 * Submission 객체를 동적으로 생성한다.
 *
 * @date 2014. 12. 9.
 * @private
 * @param {JSON} options ※options JSON형태 객체
 *  ----------------------------------------------------options arguments----------------------------------------------------
 * {String} options.id : submission 객체의 ID. 통신 모듈 실행 시 필요.
 * {String} options.ref : 서버로 보낼(request) DataCollection의 조건 표현식.(조건에 때라 표현식이 복잡하다) 또는 Instance Data의 XPath.
 * {String} options.target : 서버로 응답(response) 받은 데이터가 위치 할 DataCollection의 조건 표현식. 또는 Instance Data의 XPath.
 * {String} options.action : 통신 할 서버 측 URI.(브라우저 보안 정책으로 crossDomain은 지원되지 않는다.)
 * {String} options.method : [default: post, get, urlencoded-post] get:파라메타를 url에 붙이는 방식 (HTML과 동일).
 * post:파라메타를 body 구간에 담는 방식 (HTML과 동일) urlencoded-post:urlencoded-post.
 * {String} options.mediatype : [default: application/xml, text/xml, application/json, application/x-www-form-urlencoded]
 * application/x-www-form-urlencoded : 웹 form 방식(HTML방식). application/json : json 방식. application/xml : XML 방식. text/xml : xml방식
 * (두 개 차이는 http://stackoverflow.com/questions/4832357 참조)
 * {String} options.mode : [default: synchronous, synchronous] 서버와의 통신 방식.  asynchronous:비동기식.  synchronous:동기식
 * {String} options.encoding : [default: utf-8, euc-kr, utf-16] 서버 측 encoding 타입 설정 (euc-kr/utf-16/utf-8)
 * {String} options.replace : [default: none, all, instance] action으로부터 받은 response data를 적용 구분 값.
 * all : 문서 전체를 서버로부터 온 응답데이터로 교체.  Instance : 해당되는 데이터 구간.  None : 교체안함.
 * {String} options.processMsg : submission 통신 중 보여줄 메세지.
 * {String} options.errorHandler : submission오류 발생 시 실행 할 함수명.
 * {String} options.customHandler : submssion호출 시 실행 할 함수명.
 * {Function} options.submitHandler : {script type="javascript" ev:event="xforms-submit"} 에 대응하는 함수.
 * {Function} options.submitDoneHandler : {script type="javascript" ev:event="xforms-submit-done"} 에 대응하는 함수
 * {Function} options.submitErrorHandler : {script type="javascript" ev:event="xforms-submit-error"} 에 대응하는 함수
 * @memberOf eduCommon
 * @author InswaveSystems
 * @example
 * eduCommon.createSubmission(options);
 */
eduCommon.createSubmission = function(options) {
    var ref = options.ref || "";
    var target = options.target || "";
    var action = options.action;// 요청주소
    var mode = options.mode || eduCommon.DEFAULT_OPTIONS_MODE; //asynchronous(default)/synchronous
    var mediatype = options.mediatype || eduCommon.DEFAULT_OPTIONS_MEDIATYPE; //application/x-www-form-urlencoded
    var method = (options.method || "post"); //get/post/put/delete
    var processMsg = options.processMsg || "";
    var submitHandler = options.submitHandler || "";
    var submitDoneHandler = options.submitDoneHandler || "";
    var submitErrorHandler = options.submitErrorHandler || "";

    if ((options.isProcessMsg === true) && (processMsg === "")) {
        processMsg = "해당 작업을 처리중입니다";
    }

    var submissionObj = {
        "id" : options.id, //submission 객체의 ID. 통신 모듈 실행 시 필요.
        "ref" : ref, //서버로 보낼(request) DataCollection의 조건 표현식.(조건에 때라 표현식이 복잡하다) 또는 Instance Data의 XPath.
        "target" : target, //서버로 응답(response) 받은 데이터가 위치 할 DataCollection의 조건 표현식. 또는 Instance Data의 XPath.
        "action" : action, //통신 할 서버 측 URI.(브라우저 보안 정책으로 crossDomain은 지원되지 않는다.)
        "method" : method, //[default: post, get, urlencoded-post] get:파라메타를 url에 붙이는 방식 (HTML과 동일).
                           // post:파라메타를 body 구간에 담는 방식 (HTML과 동일).  urlencoded-post:urlencoded-post.
        "mediatype" : mediatype, //application/json
        "encoding" : "UTF-8", //[default: utf-8, euc-kr, utf-16] 서버 측 encoding 타입 설정 (euc-kr/utf-16/utf-8)
        "mode" : mode, //[default: synchronous, synchronous] 서버와의 통신 방식.  asynchronous:비동기식.  synchronous:동기식
        "processMsg" : processMsg, //submission 통신 중 보여줄 메세지.
        "submitHandler" : submitHandler, //<script type="javascript" ev:event="xforms-submit"> 에 대응하는 함수.
        "submitDoneHandler" : function(e){
    		if(submitDoneHandler){
    			var callbackFn = eval(submitDoneHandler);
    			callbackFn(e.responseText);
    		}
        }, //<script type="javascript" ev:event="xforms-submit-done"> 에 대응하는 함수
        "submitErrorHandler" : submitErrorHandler //<script type="javascript" ev:event="xforms-submit-error">에 대응하는 함수
    };

    $w.createSubmission(submissionObj);

};

/**
 * Submission 정보를 세팅한다.
 *
 * @date 2014. 12. 9.
 * @private
 * @param {Object} submissionObj 서브미션 ID
 * @param {Object} options 서브미션 옵션 (eduCommon.createSubmission의 옵션 참고)
 * @memberOf eduCommon
 * @author InswaveSystems
 * @example
 * eduCommon.setSubmission(submissionObj, options);
 */
eduCommon.setSubmission = function(submissionObj, options) {
    var ref = options.ref || "";
    var target = options.target || "";
    var action = options.action;// 요청주소
    var mode = options.mode || eduCommon.DEFAULT_OPTIONS_MODE;
    var mediatype = options.mediatype || eduCommon.DEFAULT_OPTIONS_MEDIATYPE;
    var method = (options.method || "post");
    var processMsg = options.processMsg || "";

    if ((options.isProcessMsg === true) && (processMsg === "")) {
        processMsg = "해당 작업을 처리중입니다";
    }

    var instance = options.instance || "";
    var replace = options.replace || "instance";

    submissionObj.id = options.id;
    submissionObj.ref = ref;
    submissionObj.target = target;
    submissionObj.action = action;
    submissionObj.method = method;
    submissionObj.mediatype = mediatype;
    submissionObj.encoding = "UTF-8";
    submissionObj.instance = instance;
    submissionObj.replace = replace;
    submissionObj.mode = mode;
    submissionObj.processMsg = processMsg;
};

/**
 * Submission을 수행하기 전에 실행된다.
 * 공통 설정에 적용되며 모든 submission이 영향을 받는다.
 * 현재는 submission의 action에 context가 누락된 경우의 오류를 방지하고자 url을 체크하는 로직이 구성되어있다.
 * @private
 * @date 2017. 3. 20.
 * @memberOf eduCommon
 * @author InswaveSystems
 */
eduCommon._sbm_preSubmitFunction = function(sbmObj){
	sbmObj.action = this.getURL( sbmObj.action );
};

/**
 * Submission이후 서버에서 정상 응답(200)이 왔을 때 실행된다.
 * return을 통해 error 상태로 변경이 가능하다.
 * 서버에서 내려온 상태코드를 가지고 오류가 있을 경우 log을 출력하는 기능이 구현되어있다.
 * @private
 * @date 2017. 5. 12.
 * @memberOf eduCommon
 * @author InswaveSystems
 */
eduCommon._sbm_errorHandler = function(resObj, sbmId){
	var msgObj, msgCode;
	if(resObj){
		msgCode = resObj.msgCode;
		if(msgCode && msgCode !== "S"){
			//msgObj = resObj.msgDetail;
			//if(msgObj){
			//	if(confirm(resObj.msg+"\n--------------------------\n상세 로그를 출력하시겠습니까?")){
			//		//print message and stackTrace.
			//		$w.log("--------------------------------\n message :: "+JSON.stringify(msgObj.message,null,"\t")+"\n stackTrace :: "+JSON.stringify(msgObj.stackTrace,null,"\t")+"\n--------------------------------\n");
			//	}
			//}else{
			//	alert(resObj.msg);
			//}
			return true;
		}
	}
	return false;
};
