/*
 * Copyright 2005-2007 WSO2, Inc. (http://wso2.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var wsdlObj;
var req;

var wsdl_file_not_found_error = "<p>WSDL View could not continue.</p><p>Either user has not dropped the WSDL file into the META-INF directory or the operations use message receivers other than RPC.</p>";
var definition_prefix;

function parseURL() {

    try {
		var hash=window.location.hash;
		var wsdl_file_name = hash.split('#')[1];
        if (wsdl_file_name == null){
			alert("WSDL File Could not be loaded.");
		}
        return wsdl_file_name;
    } catch (e){}

}

function initWSDLView(){
    
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
        req.onreadystatechange = processReqChangeXMLHttpRequest;
        var url = parseURL();
        req.open("GET", url, true);
        req.send(null);
    // branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
            req.onreadystatechange = processReqChangeActiveXObject;
            var url = parseURL();
            url = url + "?wsdl";
            req.open("GET", url, true);
            req.send();
        }
    }
}




function processReqChangeXMLHttpRequest() {
    // only if req shows "complete"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            // ...processing statements go here...
            wsdlObj=req.responseXML;
			if (wsdlObj.firstChild.nodeName.indexOf("definitions") < 0){
				document.getElementById("wsdlViewDiv").innerHTML = wsdl_file_not_found_error;
			} else {
				document.getElementById("wsdlViewDiv").innerHTML = generateServieTable() + "<br/><br/>" + generateMessageTable() + "<br/><br/>" + generateTypes() + "<br/><br/>";
			}
        } else {
            alert("There was a problem retrieving the XML data:\n" + req.statusText);
        }
    }

}

function processReqChangeActiveXObject()
{
    // only if req shows "complete"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            // ...processing statements go here...
            // create the XML object

            objXmlDoc = new ActiveXObject("Msxml2.DOMDocument");

            var szResponse = req.responseText;

            objXmlDoc.loadXML(szResponse);

            if (objXmlDoc.parseError.errorCode != 0) {
                var xmlErr = objXmlDoc.parseError;
                alert("You have error " + xmlErr.reason);
            }

            wsdlObj=objXmlDoc.documentElement;

            // getting the definitions prefix
            definition_prefix = wsdlObj.prefix;

			if (wsdlObj.nodeName.indexOf("definitions") < 0){
				document.getElementById("wsdlViewDiv").innerHTML = wsdl_file_not_found_error;
			} else {
				document.getElementById("wsdlViewDiv").innerHTML = generateServieTable() + "<br/><br/>" + generateMessageTable() + "<br/><br/>" + generateTypes();
			}
//			alert(document.getElementById("wsdlViewDiv").innerHTML);
            colorRows();
        } else {
            alert("There was a problem retrieving the XML data:\n" + req.statusText);
        }
    }
}

function browserSpecificGetElementsByTagName(tagObject, tagName, prifix) {
    // branch for native XMLHttpRequest object
	if (window.XMLHttpRequest) {
		return tagObject.getElementsByTagName(tagName);

	// branch for IE/Windows ActiveX version
	} else if (window.ActiveXObject) {

		return tagObject.getElementsByTagName(prifix +':' + tagName);

	}
}

function generateServieTable(){
	var disHTML = "<h2>Services</h2><table id='top_level'>\n";
//	var services = wsdlObj.getElementsByTagName("service");
	var services = browserSpecificGetElementsByTagName(wsdlObj,"service",definition_prefix);
    for (var i=0;i<services.length;i++)
	{

		var itemElm = services[i];
		if (itemElm.attributes.getNamedItem("name") != null){
			var divNameToUse = getDivName("port" + itemElm.attributes.getNamedItem("name").value);
			disHTML += "<tr><td>" +
				"<h3><a href='#' onclick=\"javascript:divShowAndHide(getElementById('" + divNameToUse + "')); return false;\">" + itemElm.attributes.getNamedItem("name").value + "</a></h3><div id='" + divNameToUse + "' style='display:inline;'>" + generatePorts(itemElm) + "</div></td></tr>\n";
		}
	}
	disHTML += "</table>\n";
    return disHTML;
}


function generatePorts(objService) {
	var disHTML = "<table width='100%'><tr><th colspan='2'>Ports</th></tr>";
	disHTML += "<tr><th>Port Name</th><th>Binding</th></tr>";
//	var ports = objService.getElementsByTagName("port");
	var ports = browserSpecificGetElementsByTagName(objService,"port",definition_prefix);
	for (var i=0;i<ports.length;i++)
	{
		var portElm = ports[i];
		if (portElm.attributes.getNamedItem("binding") != null){
			var portBinding = portElm.attributes.getNamedItem("binding").value;
			var portName = portElm.attributes.getNamedItem("name").value;
			var divNameToUse;
			if(browserSpecificGetElementsByTagName(portElm,"address","soap12")[0] != null && browserSpecificGetElementsByTagName(portElm,"address","soap12")[0].tagName.indexOf("soap12") >= 0) {
				disHTML += "<tr><td valign='top'>" + portName + "</td>";
				divNameToUse = getDivName(portName);
				disHTML += "<td valign='top'><a href='#' onclick=\"javascript:divShowAndHide(getElementById('" + divNameToUse + "')); return false;\">" + portBinding + "</a><div id='" + divNameToUse + "' style='display:inline;'>";
				disHTML += "<br/>" + browserSpecificGetElementsByTagName(portElm,"address","soap12")[0].nodeName + " location = " + browserSpecificGetElementsByTagName(portElm,"address","soap12")[0].attributes.getNamedItem("location").value;
				disHTML +=  generateBindingtable(portBinding, browserSpecificGetElementsByTagName(portElm,"address","soap12")[0].nodeName) + "</div></td></tr>";
			}

			if (browserSpecificGetElementsByTagName(portElm,"address","soap")[0] != null && (browserSpecificGetElementsByTagName(portElm,"address","soap")[0].tagName.indexOf("soap12") < 0)){
				disHTML += "<tr><td valign='top'>" + portName + "</td>";
				divNameToUse = getDivName(portName);
				disHTML += "<td valign='top'><a href='#' onclick=\"javascript:divShowAndHide(getElementById('" + divNameToUse + "')); return false;\">" + portBinding + "</a><div id='" + divNameToUse + "' style='display:inline;'>";
				disHTML += "<br/>" + browserSpecificGetElementsByTagName(portElm,"address","soap")[0].nodeName + " location = " + browserSpecificGetElementsByTagName(portElm,"address","soap")[0].attributes.getNamedItem("location").value;
				disHTML +=  generateBindingtable(portBinding, browserSpecificGetElementsByTagName(portElm,"address","soap")[0].nodeName) + "</div></td></tr>";
			}

			if (browserSpecificGetElementsByTagName(portElm,"address","soap")[0] == null && browserSpecificGetElementsByTagName(portElm,"address","soap12")[0] == null){
				disHTML += "<tr><td valign='top'>" + portName + "</td>";
				divNameToUse = getDivName(portName);
				disHTML += "<td valign='top'><a href='#' onclick=\"javascript:divShowAndHide(getElementById('" + divNameToUse + "')); return false;\">" + portBinding + "</a><div id='" + divNameToUse + "' style='display:inline;'>";
				disHTML += "<br/>" + browserSpecificGetElementsByTagName(portElm,"address","http")[0].nodeName + " location = " + browserSpecificGetElementsByTagName(portElm,"address","http")[0].attributes.getNamedItem("location").value;
				disHTML +=  generateBindingtable(portBinding, browserSpecificGetElementsByTagName(portElm,"address","http")[0].nodeName) + "</div></td></tr>";
			}
		}
//		disHTML +=  generateBindingtable(portBinding, portElm.getElementsByTagName("address")[0].nodeName) + "</div></td></tr>";
	}
	disHTML += "</table>";
	return disHTML;
}

function generateBindingtable(bindingName, bindingType){
	var disHTML = "";
	disHTML += "<ul>\n";
//	var bindings = wsdlObj.getElementsByTagName("binding");
	var bindings = browserSpecificGetElementsByTagName(wsdlObj,"binding",definition_prefix);
	//portElm.appendChild(bindings[0]);
	for (var k=0;k<bindings.length;k++){
		if (bindings[k].attributes.getNamedItem("name") != null){
            //
            var newBindingName = bindings[k].attributes.getNamedItem("name").value;
//			var newBindingType = bindings[k].getElementsByTagName("binding")[0].nodeName;
            var newBindingType;
            if (browserSpecificGetElementsByTagName(bindings[k],"binding","soap")[0] != null) {
              newBindingType = browserSpecificGetElementsByTagName(bindings[k],"binding","soap")[0].nodeName;
            }
            if(browserSpecificGetElementsByTagName(bindings[k],"binding","soap12")[0] != null) {
               newBindingType = browserSpecificGetElementsByTagName(bindings[k],"binding","soap12")[0].nodeName;
            }

            if(browserSpecificGetElementsByTagName(bindings[k],"binding","soap12")[0] == null && browserSpecificGetElementsByTagName(bindings[k],"binding","soap12")[0] == null && browserSpecificGetElementsByTagName(bindings[k],"binding","http")[0] != null) {
               newBindingType = browserSpecificGetElementsByTagName(bindings[k],"binding","http")[0].nodeName;
            }

            if (compWONS(newBindingName, bindingName) && compNS(bindingType, newBindingType)){
				bindingType = bindings[k].attributes.getNamedItem("type").value;
				var divNameToUse = getDivName(bindingType);
				disHTML += "<li>" +
								"<a href='#' onclick=\"javascript:divShowAndHide(getElementById('" + divNameToUse + "')); return false;\">portType</a>" +
								"<div id='" + divNameToUse + "' style='display:none;'>" + generateBindingTypeTable(bindingType) + "</div>";
				disHTML += "</li>\n";
				var soap_binding = browserSpecificGetElementsByTagName(bindings[k],"binding","soap")[0];
                if (soap_binding == null) {
                    soap_binding = browserSpecificGetElementsByTagName(bindings[k],"binding","soap12")[0];
                    if (soap_binding == null){
                    	soap_binding = browserSpecificGetElementsByTagName(bindings[k],"binding","http")[0];
                    }
                }
				divNameToUse = getDivName("soap:binding");
				disHTML += "<li>" +
								"<a href='#' onclick=\"javascript:divShowAndHide(getElementById('" + divNameToUse + "')); return false;\">" + soap_binding.nodeName + "</a>" +
								"<div id='" + divNameToUse + "' style='display:none;'>" +
									"<table>";
				disHTML += 			"<tr><th>type</th><th>style</th><th>transport</th></tr>";
                if (soap_binding.attributes.getNamedItem("style") == null) {
                	disHTML += 			"<tr><td>" + getNS(soap_binding.nodeName) + "</td><td>" + soap_binding.attributes.getNamedItem("verb").value + "</td><td>&nbsp;</td></tr>";
                } else {
                	disHTML += 			"<tr><td>" + getNS(soap_binding.nodeName) + "</td><td>" + soap_binding.attributes.getNamedItem("style").value + "</td><td>" + soap_binding.attributes.getNamedItem("transport").value +"</td></tr>";
                }
				disHTML += 			"</table></div>";
				disHTML += "</li>\n";

				divNameToUse = getDivName(bindingName);
				disHTML += "<li>" +
								"<a href='#' onclick=\"javascript:divShowAndHide(getElementById('" + divNameToUse + "')); return false;\">wsdl:operation</a>" +
								"<div id='" + divNameToUse + "' style='display:none;'>" + getSWDLOperationTable(bindings[k]) + "</div>" +
						   "</li>\n" ;
			}

        }

    }
    disHTML += "</ul>";
    return disHTML;
}

function generateBindingTypeTable(portName){
	var disHTML = "";
	disHTML += "<ul>\n";
//	var portTypes = wsdlObj.getElementsByTagName("portType");
	var portTypes = browserSpecificGetElementsByTagName(wsdlObj,"portType",definition_prefix);
	for (var k=0;k<portTypes.length;k++){
		if (compWONS(portName, portTypes[k].attributes.getNamedItem("name").value)){
			disHTML += "<li>Name = " + portTypes[k].attributes.getNamedItem("name").value + "</li>\n";
			disHTML += "<li>" ;
			disHTML += 		"<ul>\n";
			disHTML += 			"<li>operation</li>\n";
//			var port_type_operations = portTypes[k].getElementsByTagName("operation");
			var port_type_operations = browserSpecificGetElementsByTagName(portTypes[k],"operation",definition_prefix);
			for (var l=0;l<port_type_operations.length;l++){
				var divNameToUse = getDivName(port_type_operations[l].attributes.getNamedItem("name").value);
				disHTML += "<li>" +
				"<a href='#' onclick=\"javascript:divShowAndHide(getElementById('" + divNameToUse + "')); return false;\">" + port_type_operations[l].attributes.getNamedItem("name").value + "</a><div id='" + divNameToUse + "' style='display:none;'>" + generatePortTypeoperationTable(port_type_operations[l]) + "</div>" +
				"</li>\n" ;
//				disHTML += "<tr><td>" + port_type_operations[l].attributes.getNamedItem("name").value + generatePortTypeoperationTable(port_type_operations[l]) + "</td></tr>";
			}
			disHTML += "</ul>\n";
		}
	}

	disHTML += "</ul>\n";
	return disHTML;
}


function generatePortTypeoperationTable(port_type_operation){
	var disHTML = "";
	disHTML += "<ul>";
	var input_obj = browserSpecificGetElementsByTagName(port_type_operation,"input",definition_prefix)[0];
	var output_obj = browserSpecificGetElementsByTagName(port_type_operation,"output",definition_prefix)[0];

	var divNameToUse = getDivName(port_type_operation.attributes.getNamedItem("name").value + "input");
	if (input_obj != null){
		disHTML += "<li>" +
		"<a href='#' onclick=\"javascript:divShowAndHide(getElementById('" + divNameToUse + "')); return false;\">Input(Request)</a><div id='" + divNameToUse + "' style='display:none;'>" + getReqResPTTable(input_obj) + "</div>" +
		"</li>" ;
	}
	if (output_obj != null){
		divNameToUse = getDivName(port_type_operation.attributes.getNamedItem("name").value + "output");
		disHTML += "<li>" +
		"<a href='#' onclick=\"javascript:divShowAndHide(getElementById('" + divNameToUse + "')); return false;\">Output(Response)</a><div id='" + divNameToUse + "' style='display:none;'>" + getReqResPTTable(output_obj) + "</div>" +
		"</li>";
	}
	disHTML += "</ul>";
	return disHTML;
}

function getReqResPTTable(obj){
	var disHTML = "<ul>" +
			"<li><strong>Message</strong></li>" +
			"<li>" + obj.attributes.getNamedItem("message").value + "</li>" +
			"</ul>";
	return disHTML;
}

function generateMessageTable(){
	var disHTML = "";
	disHTML += "<h2>Messages</h2><table id='top_level' width='100%'>";
//	var messages = wsdlObj.getElementsByTagName("message");
	var messages = browserSpecificGetElementsByTagName(wsdlObj,"message",definition_prefix);
	for (var i=0;i<messages.length;i++) {
		var msgElm = messages[i];
		disHTML += "<tr><td>" + msgElm.attributes.getNamedItem("name").value + "<table  width='100%' border='1'  style='border: 1px solid #000000'>";
		disHTML += "<tr><th colspan='2'> Part </th></tr>";
		disHTML += "<tr><th width='60%'>Element</th><th width='40%'>Name</th></tr>";
//		var partElms = msgElm.getElementsByTagName("part");
		var partElms = browserSpecificGetElementsByTagName(msgElm,"part",definition_prefix);
		for (var j=0;j<partElms.length;j++){
			disHTML += "<tr><td>" + partElms[j].attributes.getNamedItem("element").value + "</td><td>" + partElms[j].attributes.getNamedItem("name").value + "</td></tr>";
		}
		disHTML += "</table></td></tr>";
	}
	disHTML += "</table>";
	return disHTML;
}

function getSWDLOperationTable(binding){
	var disHTML = "<table>";
//	var wsdl_operations = binding.getElementsByTagName("operation");
	var wsdl_operations = browserSpecificGetElementsByTagName(binding,"operation",definition_prefix);
	disHTML += "<tr><td>Name : " + binding.attributes.getNamedItem("name").value + "</td></tr>";
	for (var r=0; r<wsdl_operations.length;r++){
		if (wsdl_operations[r].attributes.getNamedItem("name") != null){
			var divNameToUse = getDivName("wsdl_operatons" + wsdl_operations[r].attributes.getNamedItem("name").value);
			disHTML += "<tr><td>" +
						"<a href='#' onclick=\"javascript:divShowAndHide(getElementById('" + divNameToUse + "')); return false;\">soap:operation</a>";
			disHTML += "<ul><li>" +
						"<div id='" + divNameToUse + "' style='display:none;'>" +
							getSOAPOperationTable(wsdl_operations[r]) +
						"</div></li>";

			var input_obj;
			if (browserSpecificGetElementsByTagName(wsdl_operations[r],"input",definition_prefix)[0] != null){
	            divNameToUse = getDivName(wsdl_operations[r].attributes.getNamedItem("name").value + "input");
				input_obj = browserSpecificGetElementsByTagName(browserSpecificGetElementsByTagName(wsdl_operations[r],"input",definition_prefix)[0],"body","soap")[0];
				if (input_obj == null) {
					input_obj = browserSpecificGetElementsByTagName(browserSpecificGetElementsByTagName(wsdl_operations[r],"input",definition_prefix)[0],"body","soap12")[0];
					if (input_obj == null) {
						input_obj = browserSpecificGetElementsByTagName(browserSpecificGetElementsByTagName(wsdl_operations[r],"input",definition_prefix)[0],"content","mime")[0];
					}
				}
	//			if (input_obj == null){
//					alert(serializingTypesObjects(browserSpecificGetElementsByTagName(wsdl_operations[r],"input",definition_prefix)[0]));
		//		}
				disHTML += "<li>" +
					"<a href='#' onclick=\"javascript:divShowAndHide(getElementById('" + divNameToUse + "')); return false;\">Input(Request)</a><div id='" + divNameToUse + "' style='display:none;'>" + getReqResTable(input_obj) + "</div>" +
					"</li>" ;
            }

			var output_obj;
			if (browserSpecificGetElementsByTagName(wsdl_operations[r],"output",definition_prefix)[0] != null){
				output_obj = browserSpecificGetElementsByTagName(browserSpecificGetElementsByTagName(wsdl_operations[r],"output",definition_prefix)[0],"body","soap")[0];
				if (output_obj == null) {
					output_obj = browserSpecificGetElementsByTagName(browserSpecificGetElementsByTagName(wsdl_operations[r],"output",definition_prefix)[0],"body","soap12")[0];
					if (output_obj == null) {
						output_obj = browserSpecificGetElementsByTagName(browserSpecificGetElementsByTagName(wsdl_operations[r],"output",definition_prefix)[0],"content","mime")[0];
					}
				}
				//alert(output_obj);
				divNameToUse = getDivName(wsdl_operations[r].attributes.getNamedItem("name").value + "output");
				disHTML += "<li>" +
					"<a href='#' onclick=\"javascript:divShowAndHide(getElementById('" + divNameToUse + "')); return false;\">Output(Response)</a><div id='" + divNameToUse + "' style='display:none;'>" + getReqResTable(output_obj) + "</div>" +
					"</li>" ;
			}
			disHTML += "</ul></td></tr>";

		}
	}
	disHTML += "</table>";
	return disHTML;
}

function getReqResTable(obj){
    var disHTML = "<table>";
			if (obj.attributes.getNamedItem("use") != null){
				disHTML += "<tr><th>use</th></tr>" +
							"<tr><td>" + obj.attributes.getNamedItem("use").value + "</td></tr>";
			} else {
				disHTML += "<tr><th>Type</th></tr>" +
							"<tr><td>" + obj.attributes.getNamedItem("type").value + "</td></tr>";
			}

			disHTML += "</table>";
	return disHTML;
}


function getSOAPOperationTable(wsdl_operation){
	var disHTML = "<table>" +
		"<tr><th>name</th><th>style</th><th>soapAction</th></tr>";
//	var soap_operations = wsdl_operation.getElementsByTagName("operation");
	var soap_operations = browserSpecificGetElementsByTagName(wsdl_operation, "operation", "soap");
	if (soap_operations.length == 0){
		soap_operations = browserSpecificGetElementsByTagName(wsdl_operation, "operation", "soap12");
	}

	if (soap_operations.length == 0){
		soap_operations = browserSpecificGetElementsByTagName(wsdl_operation, "operation", "http");
	}

	for (var d=0;d<soap_operations.length;d++){
		if (soap_operations[d].attributes.getNamedItem("style") == null){
			disHTML += "<tr><td>" + wsdl_operation.attributes.getNamedItem("name").value + "</td><td>N/A</td><td>N/A</td></tr>";
		} else {
			disHTML += "<tr><td>" + wsdl_operation.attributes.getNamedItem("name").value + "</td><td>" + soap_operations[d].attributes.getNamedItem("style").value +"</td><td>" + soap_operations[d].attributes.getNamedItem("soapAction").value +"</td></tr>";
		}
	}
	disHTML += "</table>";
	return disHTML;
}



var num = 1;
function getNewNum(){
	num++;
	return num;
}

function getDivName(name){
	return "div" + name + getNewNum();
}

function generateTypes(){
	var disHTML = "<h2>Types</h2><form action='#'><div>";
//	var types = wsdlObj.getElementsByTagName("wsdl:types");
	var types = browserSpecificGetElementsByTagName(wsdlObj,"types",definition_prefix);
	for (var i=0;i<types.length;i++) {
		disHTML += "<textarea cols='90' rows='10'>" + serializingTypesObjects(types[i]) + "</textarea>";
	}
	disHTML += "</div>";
	return disHTML;
}

function serializingTypesObjects(obj) {
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {

        return (new XMLSerializer()).serializeToString(obj);

    // branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
        return obj.xml;

    }

}

function compWONS(item1, item2) {
	var newItem1 = removeNS(item1);
	var newItem2 = removeNS(item2);
	return (newItem1 == newItem2);
}

function removeNS(text){
	var colonPos = text.lastIndexOf(":");
	var newStr = text;
	if (colonPos > 0){
		newStr = text.substring(colonPos+1, text.length);
	}
	return newStr;
}

function compNS(item1, item2) {
	var newItem1 = getNS(item1);
	var newItem2 = getNS(item2);
	return (newItem1 == newItem2);
}

function getNS(text){
	var colonPos = text.lastIndexOf(":");
	var newStr = "";
	if (colonPos > 0){
		newStr = text.substring(0, colonPos);
	}
	return newStr;
}

function divShowAndHide(objDiv){
	if (objDiv.style.display == "none"){
		objDiv.style.display = "inline";
	} else {
		objDiv.style.display = "none";
	}
}

function colorRows() {
	if (!document.getElementsByTagName) return;
	var myTR = document.getElementsByTagName('tr');
	for (var i=0;i<myTR.length;i++) {
		if (i%2) {
			myTR[i].className = 'rowTint';
		}
	}
}
    
    
