//--------------------------------------------------------------------------//
// Nexcore AJAX 공통
//
// ajax 참고 : http://www.ibm.com/developerworks/kr/series/web/index.html
// 고급자바스크립트 참고 : http://openframework.or.kr/framework_reference/prototype_js/Quick_guide_to_somewhat_advanced_JavaScript.html
//
// create by cleanhands@nate.com(jjava.net)
//--------------------------------------------------------------------------//
/**
 * NexAjax 공통 함수, 상수
 *
 * @version 1.0.0
 */
var NexAjax = {

    Version: '1.0.0',

    debug: false,

    /**
     *
     */
    NexAjax_FORMAT_DATE: 'yyyyMMdd',

    /**
     *
     */
    xmlHeader: '<?xml version="1.0" encoding="utf-8"?>',

    /**
     * Nexcore에서 사용하는 xml 객체를 만들어줍니다.
     * @param {String} txId
     * @return {Object NexcoreRequestXml}
     */
    makeXml: function(txId){
        var requestXml = new NexcoreRequestXml();
        requestXml.setTxId(txId);
        return requestXml;
    },

    /**
     * Create a new XMLHttpRequest object
     */
    createRequest: function(){
        var request;
        try {
            request = new XMLHttpRequest();
        } catch (trymicrosoft) {
            try {
                request = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (othermicrosoft) {
                try {
                    request = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (failed) {
                }
            }
        }
        if (!request)
            alert("Error initializing XMLHttpRequest!");

        return request;
    },
    /**
     * 해당 URL에 주어진 XML String을 HTTP로 전송한다.
     * 전송 후 서버로부터 응답 XML을 수신한면 xmlResponse()함수가 호출된다.
     * @param {Object} url
     * @param {Object} dom
     * @param {Object} callBackFunction
     * @param {Object} valueObject
     * @param {Object} timeout
     * @param {Object} detailyn
     */
    xmlRequest: function(url, requestXml, callBackFunction, valueObject, timeout, detailyn){

        /* Create a new XMLHttpRequest object to talk to the Web server */
        var xmlHttpRequest = null;
        try {
            xmlHttpRequest = new XMLHttpRequest();
        } catch (trymicrosoft) {
            try {
                xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (othermicrosoft) {
                try {
                    xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (failed) {
                }
            }
        }
        
        if (!xmlHttpRequest) {
            alert("Error initializing XMLHttpRequest!");
            return;
        }

        // TODO : '처리중'
        if (detailyn != 'Y') {
            //
        }

        // Define callback function
        xmlHttpRequest.onreadystatechange = function(){
            NexAjax.xmlResponse(xmlHttpRequest, callBackFunction, valueObject);
        }

        // 생성된 dom을 xmlString형식으로 변환한다.
        var xmlString = NexAjax.xmlHeader + requestXml.getXmlString();

        //test용 xmlString 확인
        //alert("test용 xmlstring: " + xmlString);

        // Open a connection to the server
        xmlHttpRequest.open("post", url, true);

        // Tell the server you're sending it XML
        xmlHttpRequest.setRequestHeader("Content-Type", "text/xml");

        // Send XML
        xmlHttpRequest.send(xmlString);

    },


    /**
     * 서버로부터 XML 응답 메시지 수신 시 호출되는 콜백 함수
     * @param {Object} xmlHttpResponse
     * @param {Object} callBackFunction
     * @param {Object} start
     * @param {Object} limit
     * @param {Object} valueObject
     */
    xmlResponse: function(xmlHttpResponse, callBackFunction, valueObject){

        // HTTP Response Ready State 검사
        /* readyState :
         0 The request is not initialized
         1 The request has been set up
         2 The request has been sent
         3 The request is in process
         4 The request is complete
         */
        if (xmlHttpResponse.readyState == 4) {

            // TODO : '처리중' 이라는 메시지 숨김
            if (false) {

            }

            // HTTP Response Code 검사
            if (xmlHttpResponse.status == 200) {
                //리턴된 xml을 dom객체로 변환.
                var returnDom = xmlHttpResponse.responseXML;

                var message = returnDom.getElementsByTagName("dataSet")[0].getElementsByTagName("message")[0];

                var result = NexAjax.getNodeValue(message, 'result');
                var messageId = NexAjax.getNodeValue(message, 'messageId');
                var messageName = NexAjax.getNodeValue(message, 'messageName');
                var messageReason = NexAjax.getNodeValue(message, 'messageReason');
                var messageRemark = NexAjax.getNodeValue(message, 'messageRemark');
                var recordSetId = NexAjax.getNodeValue(message, 'recordSetId');
                var recordId = NexAjax.getNodeValue(message, 'recordId');
                var fieldId = NexAjax.getNodeValue(message, 'fieldId');
                var exceptionStackTrace = NexAjax.getNodeValue(message, 'exceptionStackTrace');

                // TODO : 메시지 공통 처리
                if (result != 'OK') {
                    alert("[" + messageId + "]" + "\n" + messageName);
                }

                callBackFunction(new NexcoreResponseXml(returnDom), result, valueObject);

            } else if (xmlHttpResponse.status == 404) {
				alert("Request URL does not exist");
			} else if (xmlHttpResponse.status == 403) {
				alert("Access denied.");
			} else {
				alert("Status is: " + xmlHttpResponse.status+"\n\n\n Server is Error");
			}
        } else {
            //return ;
        }
    },

    /**
     *
     * @param {Object} parentNode
     * @param {String} nodeName
     */
    getNodeValue: function(parentNode, nodeName){
        var node = parentNode.getElementsByTagName(nodeName);
        if (node == null || node.length < 1) {
            return '';
        }
        if (node[0] == null || node[0].firstChild == null) {
            return '';
        }
        var nodeValue = node.item(0).firstChild.nodeValue;
        return nodeValue;

    },

    /**
     *
     * @param {Object} requestXml
     * @param {Object} form_list_paging
     * @param {Object} start
     * @param {Object} limit
     */
    makePagingInfo: function(requestXml, form_list_paging, start, limit){
        var nc_pageNo;
        var nc_recordCountPerPage;
        var startValue = start;
        var limitValue = limit;

        if (startValue == null || startValue == undefined) {
            startValue = 0;
        }
        if (limitValue == null || limitValue == undefined) {
            limitValue = form_list_paging.pageSize;
        }

        startValue = parseInt(startValue, 10);
        limitValue = parseInt(limitValue, 10);

        if (startValue == 0) {
            nc_pageNo = 1;

        } else {
            nc_pageNo = (startValue + limitValue) / limitValue;
        }

        nc_recordCountPerPage = limitValue;

        requestXml.putField("nc_start", startValue + "");
        requestXml.putField("nc_limit", limitValue + "");
        requestXml.putField("nc_pageNo", nc_pageNo);
        requestXml.putField("nc_recordCountPerPage", nc_recordCountPerPage);
    },

    /**
     * DOM을 xmlString으로 변환
     * @param {object XMLDocument} dom
     * @return {String}
     */
    makeStringByDom: function(dom){
        if (this.debug)
            alert("makeStringByDom(dom)");
        // code for IE
        var _xml = dom.xml;
        // code for Mozilla, Firefox, Opera, etc.
        if (_xml == undefined) {
            try {
                var serializer = new XMLSerializer();
                _xml = serializer.serializeToString(dom.documentElement);

                delete serializer;
            } catch (error) {
                if (this.debug)
                    alert("DOM serialization is not supported.");
            }
        }
        return _xml;
    },

    /**
     * xmlString을 dom으로 변환
     * @param {String} xmlString
     * @return {object XMLDocument}
     */
    makeDomByString: function(xmlString){
        if (this.debug)
            alert("makeDomByString(xmlString)");
        var _dom = null;
        // code for IE
        if (window.ActiveXObject) {
            _dom = new ActiveXObject("Microsoft.XMLDOM");
            _dom.async = "false";
            _dom.loadXML(xmlString);
        }
        // code for Mozilla, Firefox, Opera, etc.
        else
            if (DOMParser) {
                var parser = new DOMParser();
                _dom = parser.parseFromString(xmlString, "text/xml");
            }
            // error
            else {
                if (this.debug)
                    alert('Your browser cannot handle this script');
            }
        return _dom;
    }
};




/**
 * Nexcore 용 요청xml 객체
 */
var NexcoreRequestXml = function(){
    this.dom = NexAjax.makeDomByString('<request><transaction><id/></transaction><dataSet><fields/></dataSet></request>');
}

/**
 * Nexcore 용 요청xml 객체용 함수 (자바스크립트에선 항상 public입니다.)
 */
NexcoreRequestXml.prototype = {
    setTxId: function(txId){
        var transactionId = this.dom.getElementsByTagName("transaction")[0].getElementsByTagName("id")[0];
        transactionId.appendChild(this.dom.createTextNode(txId));
    },
    getFields: function(){
        return this.dom.getElementsByTagName("dataSet")[0].getElementsByTagName("fields")[0];
    },
    putField: function(key, value){
        var fields = this.dom.getElementsByTagName("dataSet")[0].getElementsByTagName("fields")[0];
        var field = this.dom.createElement(key);
        fields.appendChild(field);
        field.appendChild(this.dom.createTextNode(value));
    },
    createRecordSet: function(recordSetId){
        var dataSet = this.dom.getElementsByTagName("dataSet")[0];
        var recoredSet = this.dom.createElement("recordSet");
        recoredSet.setAttribute("id", recordSetId);
        dataSet.appendChild(recoredSet);
        return recoredSet;
    },
    createRecord: function(recoredSet){
        var record = this.dom.createElement("record");
        recoredSet.appendChild(record);
        return record;
    },
    putColumn: function(record, key, value){
        var column = this.dom.createElement(key);
        record.appendChild(column);
        column.appendChild(this.dom.createTextNode(value));
    },
    getXmlDOM: function(){
        return this.dom;
    },
    getXmlString: function(){
        return NexAjax.makeStringByDom(this.dom);
    }
}



/**
 * Nexcore 용 응답xml 객체
 */
var NexcoreResponseXml = function(dom){
    this.dom = dom;
}

/**
 * Nexcore 용 응답xml 객체용 함수 (자바스크립트에선 항상 public입니다.)
 */
NexcoreResponseXml.prototype = {
    getFields: function(){
        return this.dom.getElementsByTagName("dataSet")[0].getElementsByTagName("fields")[0];
    },
    getRecordSet: function(recordSetId){
        //response/dataSet/recordSet/record
        try {
            var dataSet = this.dom.getElementsByTagName("dataSet")[0];
            if (recordSetId == null || recordSetId == '') {
                var recordSet = dataSet.getElementsByTagName("recordSet")[0];
                return recordSet.getElementsByTagName("record");
            } else {
                var recordSets = dataSet.getElementsByTagName("recordSet");
                for (var i = 0; i < recordSets.length; i++) {
                    if (recordSetId == (recordSets[i].getAttribute("id") + '')) {
                        return recordSets[i].getElementsByTagName("record");
                    }
                }
                alert('getRecordSet[' + recordSetId + '] Error : RecordSet does not exist!');
                return new Array();
            }
        } catch (e) {
            if (recordSetId == null)
                recordSetId = '';
            alert('getRecordSet[' + recordSetId + '] Error : ' + e);
            return new Array();
        }
    },
    getRecordSetNode: function(recordSetId){
        //response/dataSet/recordSet/record
        try {
            var dataSet = this.dom.getElementsByTagName("dataSet")[0];
            if (recordSetId == null || recordSetId == '') {
                var recordSet = dataSet.getElementsByTagName("recordSet")[0];
                return recordSet;
            } else {
                var recordSets = dataSet.getElementsByTagName("recordSet");
                for (var i = 0; i < recordSets.length; i++) {
                    if (recordSetId == (recordSets[i].getAttribute("id") + '')) {
                        return recordSets[i];
                    }
                }
                alert('getRecordSet[' + recordSetId + '] Error : RecordSet does not exist!');
                return null;
            }
        } catch (e) {
            if (recordSetId == null)
                recordSetId = '';
            alert('getRecordSet[' + recordSetId + '] Error : ' + e);
            return null;
        }
    },
    getXmlString: function(){
        return NexAjax.makeStringByDom(this.dom);
    }
}
