﻿/* DotNetRemoting JavaScript Serializer/Deserializer */
/* function Deserial(xn) extended by Joe Korinek to support maping nodeNames to Class property Types for  known xml structures when attributes are not used */

var isIE = navigator.userAgent.toLowerCase().indexOf("msie") > -1;
var isMoz = document.implementation && document.implementation.createDocument;

// main entry for serialization  
// JavaScript object as an input
// usage: JSerialize(MyObject);
// other parameters objectName, indentSpace may be omitted
function JSerialize(ObjectToSerilize, objectName, indentSpace) {
    indentSpace = indentSpace ? indentSpace : '';

    var Type = GetTypeName(ObjectToSerilize);

    var s = indentSpace + '<' + objectName + ' type="' + Type + '">';

    switch (Type) {
        case "number":
        case "string":
        case "boolean":
            {
                s += ObjectToSerilize;
            }

            break;

        case "date":
            {
                s += ObjectToSerilize.toLocaleString();
            }
            break;

        case "array":
            {
                s += "\n";

                for (var name in ObjectToSerilize) {
                    s += JSerialize(ObjectToSerilize[name], ('index' + name), indentSpace + "   ");
                };

                s += indentSpace;
            }
            break;

        default:
            {
                s += "\n";

                for (var name in ObjectToSerilize) {
                    s += JSerialize(ObjectToSerilize[name], name, indentSpace + "   ");
                };

                s += indentSpace;
            }
            break;

    }

    s += "</" + objectName + ">\n";

    return s;
};

// main entry for deserialization
// XML string as an input
function JDeserialize(XmlText) {
    var _doc = GetDom(XmlText);
    return Deserial(_doc.childNodes[0]);
}

// get dom object . IE or Mozilla
function GetDom(strXml) {
    var _doc = null;

    if (isIE) {
        _doc = new ActiveXObject("Msxml2.DOMDocument.3.0");
        _doc.loadXML(strXml);
    }
    else {
        var parser = new DOMParser();
        _doc = parser.parseFromString(strXml, "text/xml");
    }

    return _doc;
}

// internal deserialization
function Deserial(xn) {
    var RetObj;

    var NodeType = "object";

    if (xn.attributes != null && xn.attributes.length != 0) {
        var tmp = xn.attributes.getNamedItem("type");
        if (tmp != null) {
            NodeType = xn.attributes.getNamedItem("type").nodeValue;
        }
    }
    //Added by JDK 04/03/09 to support typing by parsing class schema
    //---------------------------------------------------------------------
    else {
        var newNodeType = getTypeByNodeName(xn);
        if (newNodeType != null && newNodeType.length != 0) {
            NodeType = newNodeType;
        }
    }
    //---------------------------------------------------------------------

    if (IsSimpleVar(NodeType)) {
        if (isIE) {
            return StringToObject(xn.text, NodeType);
        }
        else {
            return StringToObject(xn.textContent, NodeType);
        }
    }

    switch (NodeType) {
        case "array":
            {
                RetObj = [];
                for (var i = 0; i < xn.childNodes.length; i++) {
                    var Node = xn.childNodes[i];
                    RetObj[i] = Deserial(Node);
                }

                return RetObj;
            }

        case "object":
        default:
            {
                try {
                    RetObj = eval("new " + NodeType + "()");
                }
                catch (e) {
                    // create generic class
                    RetObj = new Object();
                }
            }
            break;
    }

    for (var i = 0; i < xn.childNodes.length; i++) {
        var Node = xn.childNodes[i];
        RetObj[Node.nodeName] = Deserial(Node);
    }

    return RetObj;
}

function IsSimpleVar(type) {
    switch (type) {
        case "int":
        case "string":
        case "String":
        case "Number":
        case "number":
        case "Boolean":
        case "boolean":
        case "bool":
        case "dateTime":
        case "Date":
        case "date":
        case "float":
            return true;
    }

    return false;
}

function StringToObject(Text, Type) {
    var RetObj = null;

    switch (Type) {
        case "int":
            return parseInt(Text);

        case "number":
            {
                var outNum;

                if (Text.indexOf(".") > 0) {
                    return parseFloat(Text);
                }
                else {
                    return parseInt(Text);
                }
            }

        case "string":
        case "String":
            return Text;

        case "dateTime":
        case "date":
        case "Date":
            return new Date(Text);

        case "float":
            return parseFloat(Text, 10);

        case "bool":
            {
                if (Text == "true" || Text == "True") {
                    return true;
                }
                else {
                    return false;
                }
            }
            return parseBool(Text);
    }

    return RetObj;
}

function GetClassName(obj) {
    try {
        var ClassName = obj.constructor.toString();
        ClassName = ClassName.substring(ClassName.indexOf("function") + 8, ClassName.indexOf('(')).replace(/ /g, '');
        return ClassName;
    }
    catch (e) {
        return "NULL";
    }
}

function GetTypeName(ObjectToSerilize) {
    if (ObjectToSerilize instanceof Array)
        return "array";

    if (ObjectToSerilize instanceof Date)
        return "date";

    var Type = typeof (ObjectToSerilize);

    if (IsSimpleVar(Type)) {
        return Type;
    }

    Type = GetClassName(ObjectToSerilize);

    return Type;
}

//Added by JDK to support node Typing based on class schema
//---------------------------------------------------------------------
function getTypeByNodeName(xn) {
    var NodeName = xn.nodeName;
    var Type = NodeType(NodeName);
    return Type;
}

function NodeType(NodeName) {
    // map objname to type for Ct2Options and children .
    switch (NodeName) {
        //Common types: 
        case "Capacity": return "int";
        case "Count": return "int";
        case "Items": return "array";
        case "ID": return "int";
        case "IsEnabled": return "object";
        case "CRUD": return "string";
        case "Value": return "string";
        case "IsDirty": return "boolean";
        case "OriginalValue": return "string";

        // Gt2Options properties:
        case "Gt2Options": return "object";

        //Gt2Option properties:
        case "Gt2Option": return "object";

        case "IsoID": return "int";
        case "OptionID": return "int";
        case "OptionType": return "string";
        case "OptionCtrlText": return "object";
        case "OptionName": return "object";
        case "OptionIcon": return "object";
        case "OptionDescription": return "object";
        case "OptionDetails": return "object";
        case "OptionContentURL": return "object";
        case "OptionOrder": return "object";

        // Gt2Tabs properties
        case "OptionTabs": return "object";
        case "Gt2Tabs": return "object";

        //Gt2Tab properties:
        case "Gt2Tab": return "object";

        case "OptionMapID": return "int";
        case "TabID": return "int";
        case "TabTypeID": return "int";
        case "TabTitle": return "object";
        case "TabDescription": return "object";
        case "TabContentURL": return "object";
        case "TabOrder": return "object";

        //Gt2Docs properties:
        case "TabDocs": return "object";
        case "Gt2Docs": return "object";

        //Gt2Doc properties:
        case "TabDoc": return "object";
        case "Gt2Doc": return "object";


        case "TabMapID": return "int";
        case "DocID": return "int";
        case "DocName": return "object";
        case "DocDescription": return "object";
        case "DocURL": return "object";
        case "DocReportID": return "int";
        case "DocOrder": return "object";

    }
    return "";
}
//---------------------------------------------------------------------
//Added by JDK to support node Typing based on class schema