var parentPath = "";

function codeComment(c) {
    return '<span class="xmlverb-comment">' + c + '</span>\n';
}

function codeType(t) {
    return '<span class="xmlverb-element-name">' + t + '</span>';
}


function requestFCCSharpSkip(data, supports) {
    return requestFCCSharpElements(data, supports);
}

function responseFCCSharpSkip(data, supports) {
    return responseFCCSharpElements(data, supports);
}

function cSharpRequestElemValue(data, supports) {
    if (data == null) {
        return "";
    }
    var str = "";
    if (data.xmlType == "STRTYPE") {
        return '"ab"';
    }
    if (data.xmlType == "IDTYPE") {
        return '"200000-1011023419"';
    }
    if (data.xmlType == "BOOLTYPE") {
        return 'true';
    }
    if (data.xmlType == "DATETYPE") {
        return 'DateTime.Parse("12/15/2007")';
    }
    if (data.xmlType == "DATETIMETYPE") {
        return 'DateTime.Parse("12/15/2007 12:15:12"),false';
    }
    if (data.xmlType == "INTTYPE") {
        return '6';
    }
    if (data.xmlType == "AMTTYPE") {
        return '10.01';
    }
    if (data.xmlType == "PRICETYPE") {
        return '15.65';
    }
    if (data.xmlType == "PERCENTTYPE") {
        return '20.00';
    }
    if (data.xmlType == "QUANTYPE") {
        return '2';
    }
    if (data.xmlType == "GUIDTYPE") {
        return 'Guid.NewGuid().ToString()';
    }
    if (data.xmlType == "ENUMTYPE") {
        if (typeof(data.fcEnumValues) != "undefined") {
        	var tmp = data.fcEnumValues[0];
        	if (tmp.indexOf("[DEFAULT]") > 0) {
        		tmp = tmp.substring(0,tmp.indexOf("[DEFAULT]"));
        	}
            return codeType("EN" + data.fcName) + "." + tmp;
        }
    }
    return '"' + data.fcType + '"';
}

function cSharpResponseElemType(data, supports) {
    if (data == null) {
        return "";
    }
    var str = "";
    if (data.xmlType == "STRTYPE") {
        return codeType('string');
    }
    if (data.xmlType == "IDTYPE") {
        return codeType('string');
    }
    if (data.xmlType == "BOOLTYPE") {
        return codeType('bool');
    }
    if (data.xmlType == "DATETYPE" || data.xmlType == "DATETIMETYPE") {
        return codeType('DateTime');
    }
    if (data.xmlType == "INTTYPE") {
        return codeType('int');
    }
    if (data.xmlType == "AMTTYPE") {
        return codeType('double');
    }
    if (data.xmlType == "PRICETYPE") {
        return codeType('double');
    }
    if (data.xmlType == "PERCENTTYPE") {
        return codeType('double');
    }
    if (data.xmlType == "QUANTYPE") {
        return codeType('int');
    }
    if (data.xmlType == "GUIDTYPE") {
        return codeType('string');
    }
    if (data.xmlType == "ENUMTYPE") {
        if (typeof(data.fcEnumValues) != "undefined") {
            return codeType("EN" + data.fcName);
        }
    }
    return codeType(data.fcType);
}

function requestFCCSharpAttrs(data, supports) {
    //var str = ""
    //if (data.attributes != null) {
    //    var i;
    //    for (i=0; i<data.attributes.length; i++) {
    //        str += parentPath + data.attributes[i].fcName + '.SetValue( = ' + data.attributes[i].fcType + '.value;<br/>\n';
    //    }
    //}
    var str = requestFCCAttributes(data, supports);
    return str;
}

function requestFCCSharpElements(data, supports) {
    if (data == null) {
        return "";
    }
  var str = "";
  if (typeof(data.elements) != 'undefined' && data.elements != null) {
      var i;
      for (i=0; i<data.elements.length; i++) {
          str += requestFCCSharp(data.elements[i],supports);
      }
  }
  return str;
}

function responseFCCSharpElements(data, supports) {
    if (data == null) {
        return "";
    }
  var str = "";
  if (typeof(data.elements) != 'undefined' && data.elements != null) {
      var i;
      for (i=0; i<data.elements.length; i++) {
          str += responseFCCSharp(data.elements[i],supports);
      }
  }
  return str;
}

function requestFCCSharpOR(data, supports) {
    if (data == null) {
        return "";
    }
    var str = "";
    var oldParent = parentPath;
    if (typeof(data.fcListOf) != "undefined") {
    	var varname = getVariable(data.fcName + 'Element');
    	str += codeType(data.fcListOf.fcType) + ' ' + varname + ' =' + parentPath + data.fcName + '.Append();<br/>\n';
    	parentPath = varname + '.'; 
    } else {
    	parentPath = parentPath + data.fcName + ".";  
    }
	if (typeof(data.elements) != 'undefined' && data.elements != null) {
    	var i;
    	var varname = getVariable(data.fcName + 'ElementType');
    	str += codeType('string ') + varname + ' = "' + data.elements[0].fcName + '";' + '<br/>';
    	for (i=0; i<data.elements.length; i++) {
	    	str += 'if (' + varname + ' == "' + data.elements[i].fcName + '")' + '<br/>';
	    	str += '{<div class="codeverb-indent">\n';
    	    str += requestFCCSharp(data.elements[i],supports);
        	str += '</div>\n}<br/>\n';
    	}
	}
    parentPath = oldParent;
    return str;
}

function responseFCCSharpOR(data, supports) {
    if (data == null) {
        return "";
    }
    var str = "";
    var oldParent = parentPath;
    str += "if (" + parentPath + data.fcName + " != null)<br/>\n";
	str += '{<div class="codeverb-indent">\n';
	var haveLoop = 0;
	if (typeof(data.fcListOf) != "undefined") {
		haveLoop = 1;
		var varname = getVariable('i');
		str += 'for (' + codeType('int ') + varname + ' = 0; ' + varname + ' &lt; ' + parentPath + data.fcName + '.Count; ' + varname + '++)<br/>\n';
		str += '{<div class="codeverb-indent">\n';
		str += codeType(data.fcListOf.fcType) + ' ' + data.fcListOf.fcType.substring(1) + ' = ' + parentPath + data.fcName + '.GetAt(' + varname + ');<br/>\n';
		parentPath = data.fcListOf.fcType.substring(1) + '.';
	} else {
		parentPath = parentPath + data.fcName + ".";
	}
	var i;
	for (i=0; i<data.elements.length; i++) {
	    str += 'if (' + parentPath + data.elements[i].fcName + ' != null)<br/>\n';
		str += '{<div class="codeverb-indent">\n';
		str += responseFCCSharp(data.elements[i], supports);
		str += '</div>\n}<br/>\n';	
	}
	if (haveLoop > 0) {
		str += '</div>\n}<br/>\n';
	}	
	str += '</div>\n}<br/>\n';
	parentPath = oldParent;
	return str;
}

function requestFCCSharpAggregate(data, supports) {
    if (data == null) {
        return "";
    }
    var str = "";
    var oldParent = parentPath;
    if (typeof(data.fcListOf) != "undefined" && data.fcListOf != null) {
    	var varname = getVariable(data.xmlName);
        str += codeType(data.fcListOf.fcType) + ' ' + varname + '=' + parentPath + data.fcName + '.Append();<br/>\n';
        parentPath = varname + '.';
    } else {
        if (data.fcType != "nothing") {
        	parentPath += data.fcName + '.';
        }
    }
    str += requestFCCSharpAttrs(data, supports);
    str += requestFCCSharpElements(data, supports);
    parentPath = oldParent;
    return str;
}

function responseFCCSharpAggregate(data, supports) {
    if (data == null) {
        return "";
    }
    var str = "";
    var oldParent = parentPath;
    if (typeof(data.fcListOf) != "undefined" && data.fcListOf != null) {
        str += 'if (' + parentPath + data.fcName + ' != null)<br/>\n';
		str += '{<div class="codeverb-indent">\n';
		var varname = getVariable('i');
		str += 'for (' + codeType('int ') + varname + ' = 0; ' + varname + ' &lt; ' + parentPath + data.fcName + '.Count; ' + varname + '++)<br/>\n';
		str += '{<div class="codeverb-indent">\n';
		str += codeType(data.fcListOf.fcType) + ' ' + data.fcListOf.fcType.substring(1) + ' = ' + parentPath + data.fcName + '.GetAt(' + varname + ');<br/>\n';
		parentPath = data.fcListOf.fcType.substring(1) + '.';
		str += responseFCCSharpElements(data, supports);
		str += '</div>\n}<br/>\n';			
		str += '</div>\n}<br/>\n';	
    } else {
        if (!data.required) {
            str += 'if (' + parentPath + data.fcName + ' != null)<br/>\n';
			str += '{<div class="codeverb-indent">\n';
	    }   
        parentPath = parentPath + data.fcName + ".";
        str += responseFCCSharpElements(data, supports);
        if (!data.required) {
            str += '</div>\n}<br/>\n';
        }
    }
    parentPath = oldParent;
    return str;
}
        

function requestFCCAttributes(data, supports)
{
    if (data == null) {
        return "";
    }
  var str = "";
  if (typeof(data.attributes) != 'undefined' && data.attributes != null) {
      if (data.attributes.length > 0) {
          str += codeComment('//Set attributes<br/>\n');
      	  var i;
          for (i=0; i<data.attributes.length; i++) {
              str += requestFCCSharpElement(data.attributes[i],supports);
          }
       }
          
//          for (j=0; j<data.attributes.length; j++) {
//              str += parentPath + data.fcName + '.' + data.attributes[j].fcName + '.SetValue(' + cSharpRequestElemValue(data.attributes[j], supports) + ');<br/>\n';
//          }
  }
  return str;   
}

function requestFCCSharpElement(data, supports)
{
    if (data == null) {
        return "";
    }
    var str = "";
    
    str += codeComment('//Set field value for ' + data.fcName + '<br/>');
    if (typeof(data.count) != "undefined" && typeof(data.count) == "string" && data.count.indexOf("n") >= 0) {
        str += codeComment("//May create more than one of these if needed<br/>");
        str += parentPath + data.fcName + '.Add(' + cSharpRequestElemValue(data, supports) + ');<br/>\n';
    } else {
    	str += parentPath + data.fcName + '.SetValue(' + cSharpRequestElemValue(data, supports) + ');<br/>\n';
    	str += requestFCCAttributes(data, supports);
    }
    return str;
}

function responseFCCSharpElement(data, supports)
{
    if (data == null) {
        return "";
    }
    var str = "";
    str += codeComment('//Get value of ' + data.fcName + '<br/>');
    var varname = getVariable(data.xmlName);
    if (data.required) {
        str += codeType(cSharpResponseElemType(data, supports)) + ' ' + varname + ' = (' + codeType(cSharpResponseElemType(data, supports)) + ')' + parentPath + data.fcName + '.GetValue();<br/>\n';
    } else {
        str += 'if (' + parentPath + data.fcName + ' != null)<br/>\n';
		str += '{<div class="codeverb-indent">\n';
        str += codeType(cSharpResponseElemType(data, supports)) + ' ' + varname + ' = (' + codeType(cSharpResponseElemType(data, supports)) + ')' + parentPath + data.fcName + '.GetValue();<br/>\n';
		str += '</div>\n}<br/>\n';		
    }	   
    return str;
}

function requestFCCSharp(data,parentSupports) {
    if (data == null) {
        return "";
    }
  var colspan;
  var str = ""
  var supports = updateSupports(parentSupports, data);
  if (!supportsCheckedEditions(supports)) {
      return str;
  }
  if (!checkSDKVers(data)) {
      return str;
  }
  if (!data.fcType) {
      return str;
  } else if (data.fcType == "skip") {
      str += requestFCCSharpSkip(data, supports);
  } else if (data.xmlType == "OR") {
      str += requestFCCSharpOR(data, supports);
  } else if (data.xmlType == "Aggregate" || data.xmlType == "List" || data.xmlType == "skip") {
      str += requestFCCSharpAggregate(data, supports);
  } else {
      str += requestFCCSharpElement(data, supports);
  }
  return str;
}

function responseFCCSharp(data, parentSupports) {
    if (data == null) {
        return "";
    }
    var str = "";
    var supports = updateSupports(parentSupports, data);
    if (!supportsCheckedEditions(supports)) {
        return str;
    }
    if (!checkSDKVers(data)) {
        return str;
    }
    if (!data.fcType) {
        return str;
    } else if (data.fcType == "skip") {
        str += responseFCCSharpSkip(data, supports);
    } else if (data.xmlType == "OR") {
        str += responseFCCSharpOR(data, supports);
    } else if (data.xmlType == "Aggregate") {
        str += responseFCCSharpAggregate(data, supports);
    } else if (data.xmlType == "List") {
        str += responseFCCSharpAggregate(data, supports);
    } else {
        str += responseFCCSharpElement(data, supports);
    }
    return str;
}

function FCCSharpBuild(data, supports) {
    if (data == null) {
        return "";
    }
    var str = "";
    str += codeType('void') + ' Build' + data.xmlName + '(' + codeType('IMsgSetRequest') + ' requestMsgSet)<br/>\n';
    str += '{<div class="codeverb-indent">\n';
    str += codeType(data.fcName) + ' ' + data.xmlName + '= requestMsgSet.Append' + _vars['selectedMsg'] + 'Rq();<br/>\n'
    parentPath =  data.xmlName + ".";
    str += requestFCCSharp(data, supports);
    str += '</div>\n';
    str += '}<br/><br/>\n';
    return str;
}

function FCCSharpParse(data, supports) {
    if (data == null) {
        return "";
    }
    var str = "";
    str += codeType('void') + ' Walk' + data.xmlName + '(' + codeType('IMsgSetResponse') + ' responseMsgSet)<br/>\n';
    str += '{<div class="codeverb-indent">\n';
    str += 'if (responseMsgSet == null) return;<br/><br/>\n';
    str += codeType('IResponseList') + ' responseList = responseMsgSet.ResponseList;<br/>\n';
    str += 'if (responseList == null) return;<br/><br/>\n';
    str += codeComment("//if we sent only one request, there is only one response, we'll walk the list for this sample<br/>");
    str += 'for (int i=0; i&lt;responseList.Count; i++)<br/>\n';
    str += '{<div class="codeverb-indent">\n';
    str += codeType('IResponse') + ' response = responseList.GetAt(i);<br/>\n';
    str += codeComment('//check the status code of the response, 0=ok, >0 is warning<br/>');
    str += 'if (response.StatusCode &gt;= 0)<br/>\n';
    str += '{<div class="codeverb-indent">\n';
    str += codeComment('//the request-specific response is in the details, make sure we have some<br/>');
    str += 'if (response.Detail != null)<br/>\n';
    str += '{<div class="codeverb-indent">\n';
    str += codeComment("//make sure the response is the type we're expecting<br/>");
    str += codeType('ENResponseType') + ' responseType = (' + codeType('ENResponseType') + ')response.Type.GetValue();<br/>\n';
    str += 'if (responseType == ' + codeType('ENResponseType') + '.rt' + data.xmlName + ')<br/>\n';
    str += '{<div class="codeverb-indent">\n';
    if (typeof(data.elements) != "undefined" && data.elements != null) {
        var detail = data.elements[0];
        str += codeComment('//upcast to more specific type here, this is safe because we checked with response.Type check above<br/>');
    	str += codeType(detail.fcType) + ' ' + detail.xmlName + ' = (' + codeType(detail.fcType) + ')response.Detail;<br/>\n';
    	str += '<b>Walk' + detail.xmlName + '(' + detail.xmlName + ');</b><br/>\n';
    }
    str += '</div>\n}<br/>\n';
    str += '</div>\n}<br/>\n';
    str += '</div>\n}<br/>\n';
    str += '</div>\n}<br/>\n';
    str += '</div>\n}<br/>\n';
    str += '<br/><br/><br/>\n';
    if (typeof(data.elements) != "undefined" && data.elements != null) {
        var detail = data.elements[0];
     	str += 'void Walk' + detail.xmlName + '(' + codeType(detail.fcType) + ' ' + detail.xmlName + ')<br/>\n';
        str += '{<div class="codeverb-indent">\n';
        str += 'if (' + detail.xmlName + ' == null) return;<br/><br/>\n';
        parentPath = detail.xmlName + '.';
        str += codeComment('//Go through all the elements of ' + detail.fcType + '<br/>');
        str += responseFCCSharpElements(detail, supports);
	    str += '</div>\n}<br/>\n';
	    str += '<br/><br/><br/>\n';
    }
    return str;
}    

function FCCSharpHeader() 
{
    var str = "";
    str += codeComment("//The following sample code is generated as an illustration of <br/>");
    str += codeComment("//Creating requests and parsing responses ONLY<br/>");
    str += codeComment("//This code is NOT intended to show best practices or ideal code<br/>");
    str += codeComment("//Use at your most careful discretion<br/><br/>");
    str += 'using System;<br/>\n';
    str += 'using System.Net;<br/>\n';
    str += 'using System.Drawing;<br/>\n';
    str += 'using System.Collections;<br/>\n';
    str += 'using System.ComponentModel;<br/>\n';
    str += 'using System.Windows.Forms;<br/>\n';
    str += 'using System.Data;<br/>\n';
    str += 'using System.IO;<br/>\n';
    str += 'using Interop.QBFC7;<br/>\n';
    str += '<br/>\n';
    str += 'namespace <span class="xmlverb-ns-name">com.intuit.idn.samples</span><br/>\n';
    str += '{<div class="codeverb-indent">\n';
    str += 'public class Sample<br/>\n';
    str += '{<div class="codeverb-indent">\n';
    str += 'public void Do' + _vars['selectedMsg'] + '()<br/>\n';
    str += '{<div class="codeverb-indent">\n';
    str += codeType('bool') + ' sessionBegun = false;<br/>\n';
    str += codeType('bool') + ' connectionOpen = false;<br/>\n';
    str += codeType('QBSessionManager') + ' sessionManager = null;<br/><br/>\n';
    str += 'try<br/>\n';
    str += '{<div class="codeverb-indent">\n';
    str += codeComment('//Create the session Manager object<br/>\n');
    str += 'sessionManager = new QBSessionManager();<br/><br/>\n';
    str += codeComment('//Create the message set request object to hold our request<br/>');
    var major = maxSDK.substring(0,1);
    var minor = maxSDK.substring(2);
    str += codeType('IMsgSetRequest') + ' requestMsgSet = sessionManager.CreateMsgSetRequest("US",' + major + ',' + minor + ');<br/>\n';
    str += 'requestMsgSet.Attributes.OnError = ENRqOnError.roeContinue;<br/><br/>\n';
    str += '<b>Build' + _vars['selectedMsg'] + 'Rq(requestMsgSet);</b><br/><br/>\n';
    str += codeComment('//Connect to QuickBooks and begin a session<br/>');
    str += 'sessionManager.OpenConnection("","Sample Code from OSR");<br/>\n';
    str += 'connectionOpen = true;<br/>\n';
    str += 'sessionManager.BeginSession("", ENOpenMode.omDontCare);<br/>\n';
    str += 'sessionBegun = true;<br/><br/>\n';
    str += '//Send the request and get the response from QuickBooks<br/>\n';
    str += codeType('IMsgSetResponse') + ' responseMsgSet = sessionManager.DoRequests(requestMsgSet);<br/><br/>\n';
    str += codeComment('//End the session and close the connection to QuickBooks<br/>');
    str += 'sessionManager.EndSession();<br/>\n';
    str += 'sessionBegun = false;<br/>\n';
    str += 'sessionManager.CloseConnection();<br/>\n';
    str += 'connectionOpen = false;<br/><br/>\n';
    str += '<b>Walk' + _vars['selectedMsg'] + 'Rs(responseMsgSet);</b><br/><br/>\n';
    str += '</div>\n';
    str += '}<br/>\n';
    str += 'catch (Exception e)<br/>\n';
    str += '{<div class="codeverb-indent">\n';
    str += 'MessageBox.Show(e.Message, "Error");<br/>\n';
    str += 'if (sessionBegun)<br/>\n';
    str += '{<div class="codeverb-indent">\n';
    str += 'sessionManager.EndSession();<br/>\n';
    str += '</div>\n';
    str += '}<br/>\n';
    str += 'if (connectionOpen)<br/>\n';
    str += '{<div class="codeverb-indent">\n';
    str += 'sessionManager.CloseConnection();<br/>\n';
    str += '</div>\n';
    str += '}<br/>\n';
    str += '</div>\n';
    str += '}<br/>\n';
    str += '</div>\n';
    str += '}<br/><br/><br/>\n';
    return str;
}
 

function renderFCCSharpCode(targ) {
    showUS = _vars['showUS'][0];
    showOE = _vars['showOE'][0];
    showCA = _vars['showCA'][0];
    showUK = _vars['showUK'][0];
    datadir = _vars['dataDir'][0];
    indent = "";
    var msgData = _vars['messageDataJSON'][0];
    var messageDataJSON;
    if (msgData != "") {
        messageDataJSON = eval('(' + msgData + ')');
    }
    var respData = _vars['responseData'][0];
    var respDataJSON;
    if (respData != "") {
        respDataJSON = eval('(' + respData + ')');
    }
    rowcount = 0;
    maxSDK = _vars['maxSDKVersion'][0];
    var supports = {US:true, CA:true, UK:true, OE:true};
    var content = '<b:xhtml>\n';
    content += FCCSharpHeader();
    content += FCCSharpBuild(messageDataJSON, supports);
    content += '<br/><br/><br/>\n';
    content += FCCSharpParse(respDataJSON, supports);
    content += '</div>\n';
    content += '}<br/>\n';
    content += '</div>\n';
    content += '}<br/>\n';
    content += '</b:xhtml>\n';
    //alert(content)
    //content += requestFCCSharp(data, supports);
    bpc.render(content,'replacechildren', targ);
    //bpc.task(['b:action', 'settext', 'b:value', content], _current);
    return content;
}

