<script type="text/javascript">
//<![CDATA[
		 var ApiKey = 'AIzaSyDXCinRv4ZCG1bIHZArGyTkAvS7Rg7synU';
         var BaseURL = {'sheets':'https://sheets.googleapis.com/v4/spreadsheets/'};
         var ComplexDatatypes = {
             'CWE_1':true,
             'CWE_2':true,
             'CWE_3':true,
             'CX':true,
             'DTM_1':true,
             'DTM_2':true,
             'DTM_3':true,
             'DTM_4':true,
             'EI':true,
             'FN':true,
             'HD_1':true,
             'HD_2':true,
             'MSG':true,
             'PT':true,
             'VID':true,
             'XCN_1':true,
             'XCN_2':true,
             'XPN':true};

         var CachedSheets = { };
             
         // Generic AJAX GET client, handles variable number of arguments. 
         // All arguments are then passed to the call-back function, 
         // with the addition of the HTTP response body (passed as 
         // the first argument to the call-back function.
         var HttpClient = function() {
             var args = Array.prototype.slice.call(arguments);
             this.get = function(url, callback) {
                 var httpRequest = new XMLHttpRequest();
                 httpRequest.onreadystatechange = function() { 
                     if (httpRequest.readyState == 4 && httpRequest.status == 200) {
                         args.unshift(httpRequest.responseText);
                         callback.apply(null, args);
                     }
                 }

                 httpRequest.open( "GET", url, true );            
                 httpRequest.send( null );
             }
         }

         // Toggle hidden rows to display/hide details of the object in question
         function segToggle(elementId)
         {
             var row = document.getElementById(elementId);
             var itemId = 'Cell_' + elementId;
             var expand = document.getElementById(itemId);
             if ((row.style.display == 'none') || (row.style.display == '')) 
             {
                 row.style.display = 'table-row';
                 expand.innerText = '\u229f';
             }
             else
             {
                 row.style.display = 'none';
                 expand.innerText = '\u229e';
             }
             
         }

         function _lastWord(source) {
             return (""+source).replace(/[\s-]+$/,'').split(/[\s-]/).pop();
         }

         function _required(reqFlag) {
             reqFlag = reqFlag.replace(/[\ ]/g,'');
             //simple case of required
             if ((reqFlag == 'r') || (reqFlag == 're')) 
             {
                 return true;
             }
             //not required and not conditional
             if (reqFlag.charAt(0) != 'c')
             {
                 return false;
             }
             //handle conditional
             var matches = reqFlag.match(/\((.*?)\)/);
             if (matches)
             {
                 var conditions = matches[1].split('/');
                 for (var i = 0; i< conditions.length; i++)
                 {
                     if ((conditions[i] == 'r') || (conditions[i] == 're')) 
                     {
                         return true;
                     }
                 }
                 
             }
             //Conditional, but none of the conditions is required
             return false;
         }

         // Generic toggle function
         function JBtoggle(ItemID) {
			if( document.getElementById(ItemID).style.display=='none' ) {
				document.getElementById(ItemID).style.display = 'block';
			}
			else {
				document.getElementById(ItemID).style.display = 'none';
			}
		 }
         //Base Data types
         function getBDT(spreadsheetId, sheetName) {
             var url = BaseURL.sheets + spreadsheetId + '/values/' + sheetName + '?key=' + ApiKey;
             var client = new HttpClient(sheetName);
             client.get(url, _processBDTResponse);
         }
         function _processBDTResponse(response, sheetName) {
             var divId = 'div' + sheetName;
             var values = JSON.parse(response).values;
             var title = values[0][0];
             var table = document.createElement('table');
             table.setAttribute('class','msgTable');
             var tableContent = _setBDTHeader(values);
             var colNum = values[1].length;
             for (var i=2; i < values.length; i++)
             {
                 tableContent = tableContent + '<tr>\n';
                 for (var j=0; j < colNum; j++)
                 {
                     value = values[i][j];
                     if (value == null)
                     {
                         value="";
                     }
                     cellStyle = '<td class="msgTable">';
                     if (j == 0)
                     {
                         cellStyle = '<td class="msgTable bdtAbbr">';
                     }
                     else if (j == 2)
                     { 
                         value = value.replace(/(?:\r\n|\r|\n)/g, '<br />');
                     }
                     tableContent = tableContent + cellStyle + value + '<\/td>\n';
                 }
                 tableContent = tableContent + '<\/tr>\n';
             }
             table.innerHTML = tableContent;
             var div = document.getElementById(divId);
             div.appendChild(table);
         }
         function _setBDTHeader(values) {
             //var content='<tr>\n<td colspan="' + values[1].length + '" class="msgTable title">' + values[0][0] + '<\/td>\n<\/tr>\n<tr>\n';
             var content='<tr>\n';
             for (var j=0; j < values[1].length; j++)
             {
                 content = content + '<th class="msgTable bdtCol' + j + '">' + values[1][j] + '<\/th>\n';
             }
             content = content + '<\/tr>\n';
             return content;         
         }

         //Manage data types within segments
         function storeDatatype(datatypes, type, elementId) {
             datatypes.elements[elementId] = type;
         }
         function getDatatypes(datatypes,level) {
             var spreadsheetId = '1p4sajtiJvRppCe3YKDa2WB-YW9azN87NSPUBa_ulRVQ';
             var colNum = datatypes.span;
             var url = ""
             var sheetName = "";
             var client =  null;
             for (var elementId in datatypes.elements)
             {
                 sheetName = datatypes.elements[elementId];
                 if (sheetName in CachedSheets)
                 {
                     _processDatatypeResponse("", elementId, colNum, sheetName, level);
                 }
                 else
                 {
                     url = BaseURL.sheets + spreadsheetId + '/values/' + sheetName + '?key=' + ApiKey;
                     getDatatypeDelayed(url, elementId, colNum, sheetName, level);
                 }
             }
         }
         function getDatatypeDelayed(url, elementId, colNum, sheetName, level) {
             window.setTimeout(function() {
                 if (sheetName in CachedSheets)
                 {
                     _processDatatypeResponse("", elementId, colNum, sheetName, level);
                 }
                 else
                 {
                     var client = new HttpClient(elementId, colNum, sheetName, level);
                     client.get(url, _processDatatypeResponse);
                 }
             }, 400);
         }
         function _processDatatypeResponse(response, elementId, span, sheetName, level) {
             var result = '<td colspan="' + span + '" class="msgTable dtRow">\n<table class="msgTable dtTable' +level + '">\n';
             var values = "";
             if (response == "")
             {
                 values = CachedSheets[sheetName];
             }
             else
             {
                 values = JSON.parse(response).values;
                 CachedSheets[sheetName] = values;
             }
             result = result + _setDatatypeHeader(values, level);
             var datatype = "";
             var isComplexDatatype = false;
             var subTypes = new Object;
             subTypes.elements = new Object;
             var reqFlag = "";
             var cellStyle = "";
             var value = "";
             var typeElementId = "";
             var colNum = values[1].length;
             subTypes.span = colNum;
             for (var i=2; i < values.length; i++)
             {
                 reqFlag = (values[i][3] + "").toLowerCase();
                 if ((!_required(reqFlag)) && (reqFlag != 'varies')) {
                     continue;
                 }
                 datatype = values[i][2].replace(/[\ ]/g,'').toUpperCase();
                 isComplexDatatype = datatype in ComplexDatatypes;
                 result = result + '<tr>\n';
                 for (var j=0; j < colNum; j++)
                 {
                     value = values[i][j];
                     if (value == null)
                     {
                         value="";
                     }
                     cellStyle = '<td class="msgTable">';
                     if (j == 0)
                     {
                         cellStyle = '<td class="msgTable segSeq">';
                         //value = datatype + '_' + value;
                         if (isComplexDatatype)
                         {
                             typeElementId = elementId + '_' + datatype + '_' + i;
                             value = '<div id="Cell_' + typeElementId + '" class="expand2" onClick="segToggle(\'' + typeElementId + '\')">\u229e<\/div>' + value;
                         }
                     }
                     else if ( (j > 1) && (j < 5) )
                     {
                         cellStyle = '<td class="msgTable col' + j + '">';
                     }
                     else if (j == 5)
                     { 
                         value = value.replace(/(?:\r\n|\r|\n)/g, '<br />');
                     }
                     result = result + cellStyle + value + '<\/td>\n';
                 }
                 result = result + '<\/tr>\n';
                 if (isComplexDatatype)           //build the dataype table
                 {
                     result = result + '<tr id="' + typeElementId + '" class="hide"><\/tr>\n';
                     storeDatatype(subTypes, datatype, typeElementId);
                 }
             }
             result = result + '<\/table>\n<\/td>\n';
             var row = document.getElementById(elementId);
             row.innerHTML = result;
             if (Object.keys(subTypes.elements).length>0)
             {
                 getDatatypes(subTypes, level+1);
             }
         }
         function _setDatatypeHeader(values, level) {
             var content='<tr>\n';
             for (var j=0; j < values[1].length; j++)
             {
                 content = content + '<th class="msgTable dt' + level + 'Col' + j + '">' + values[1][j] + '<\/th>\n';
             }
             content = content + '<\/tr>\n';
             return content;
         }

         //Manage Messages
         function getMessageDelayed(sheetName,factor) {
             window.setTimeout(function() {
                 getMessage(sheetName);
             }, factor * 750);
         }
         function getMessage(sheetName) {
             var spreadsheetId = '1etoDlL1LbvFBmIlc0jm4sIR-wv0zFYHZmqx6I8r4hWc';
             var url = BaseURL.sheets + spreadsheetId + '/values/' + sheetName + '?key=' + ApiKey;
             var client = new HttpClient(sheetName);
             client.get(url, _processMsgResponse);
         }
         function _processMsgResponse(response, sheetName) {
             var msgId = sheetName.split('^')[0] + '_' + sheetName.split('^')[1];
             var divId = 'div' + msgId;
             var values = JSON.parse(response).values;
             var title = values[0][0];
             var table = document.createElement('table');
             table.setAttribute('class','msgTable');
             var tableContent = _setTableHeader(values);
             var level = 0;
             var exLevel = 0;
             var exclude = false;
             var testWord = "";
             var reqFlag = "";
             var value="";
             var cellStyle=""
             var colNum = values[1].length;
             var isGroupRow = true;
             var segments = new Object;
             segments.elements = new Object;
             segments.span = colNum;
             var segmentId = "";
             var elementId = "";
             for (var i=2; i < values.length; i++)
             {
                 level = (values[i][0].match(/\u21E8/g) || []).length; //number of leading arrows determines the nesting level
                 testWord = _lastWord(values[i][1].toLowerCase());
                 isGroupRow = (testWord == 'begin') || (testWord == 'end');
                 if (exclude)    //we are in an exclusion range, check for end of range
                 {
                     if ((level == exLevel) && (testWord == 'end'))
                     {
                         exclude = false;
                     }
                     continue;
                 }
                 reqFlag = (values[i][2] + "").toLowerCase();
                 if (!_required(reqFlag))
                 {
                     if (testWord == 'begin')  //start exclusion range
                     {
                        exLevel = level;
                        exclude = true;
                     }
                     if (testWord != 'end')   //catch closure of non-excluded group
                     {
                         continue;
                     }
                 }
                 tableContent = tableContent + '<tr>\n';
                 for (var j=0; j < colNum; j++)
                 {
                     value = values[i][j];
                     if (value == null)
                     {
                         value="";
                     }
                     cellStyle = '<td class="msgTable">';
                     if ( (j == 2) || j == 3)
                     {
                         cellStyle = '<td class="msgTable col' + j + '">';
                     }
                     if ( (j == 1) && isGroupRow)
                     {
                         cellStyle = '<td class="msgTable group">';
                     }
                     if ( (j == 0) && (!isGroupRow))
                     {
                         segmentId = value.substring(level).replace(/[\[\]\ {}]/g,'');
                         elementId = '360X_'+ msgId + '_' + segmentId + '_' + i;
                         value = value + '<div id="Cell_' + elementId + '" class="expand" onClick="segToggle(\'' + elementId + '\')">\u229e<\/div>';
                     }
                     if (j == 4 )
                     { 
                         value = value.replace(/(?:\r\n|\r|\n)/g, '<br />');
                     }
                     tableContent = tableContent + cellStyle + value + '<\/td>\n';
                 }
                 tableContent = tableContent + '<\/tr>\n';
                 if (!isGroupRow)           //build the segment table
                 {
                     tableContent = tableContent + '<tr id="' + elementId + '" class="hide"><\/tr>\n';
                     storeSegment(segments, segmentId, elementId);
                 }
             }
             //appendPre(tableContent);
             table.innerHTML = tableContent;
             var div = document.getElementById(divId);
             div.appendChild(table);
             getSegments(segments);
         }
                 
         function _setTableHeader(values) {
             var content='<tr>\n<td colspan="' + values[1].length + '" class="msgTable title">' + values[0][0] + '<\/td>\n<\/tr>\n<tr>\n';
             for (var j=0; j < values[1].length; j++)
             {
                 content = content + '<th class="msgTable col' + j + '">' + values[1][j] + '<\/th>\n';
             }
             content = content + '<\/tr>\n';
             return content;
         }

		 //Manage segments within messages
         function storeSegment(segments, segmentId, elementId) {
             segments.elements[elementId]=segmentId;
         }
         function getSegments(segments) {
             var spreadsheetId = '14ahx-hgr92L3nCZlOexHEdxJX9uL8IoMqnnp0z-M-98';
             var colNum = segments.span;
             var url = ""
             var sheetName = "";
             var client =  null;
             for (var elementId in segments.elements)
             {
                 sheetName = segments.elements[elementId];
                 if (sheetName in CachedSheets)
                 {
                     _processSegResponse("", elementId, colNum, sheetName);
                 }
                 else
                 {
                     url = BaseURL.sheets + spreadsheetId + '/values/' + sheetName + '?key=' + ApiKey;
                     client = new HttpClient(elementId, colNum, sheetName);
                     client.get(url, _processSegResponse);
                 }
             }
         }
         function _processSegResponse(response, elementId, span, sheetName) {
             var result = '<td colspan="' + span + '" class="msgTable segRow">\n<table class="msgTable segTable">\n';
             var values = "";
             if (response == "")
             {
                 values = CachedSheets[sheetName];
             }
             else
             {
                 values = JSON.parse(response).values;
                 CachedSheets[sheetName] = values;
             }
             var result = result + _setSegHeader(values);
             var datatype = "";
             var isComplexDatatype = false;
             var types = new Object;
             types.elements = new Object;
             var reqFlag = "";
             var cellStyle = "";
             var value = "";
             var typeElementId = "";
             var colNum = values[1].length;
             types.span = colNum
             for (var i=2; i < values.length; i++)
             {
                 reqFlag = (values[i][3] + "").toLowerCase();
                 if ((!_required(reqFlag)) && (reqFlag != 'varies')) {
                     continue;
                 }
                 datatype = values[i][2].replace(/[\ ]/g,'').toUpperCase();
                 isComplexDatatype = datatype in ComplexDatatypes;
                 result = result + '<tr>\n';
                 for (var j=0; j < colNum; j++)
                 {
                     value = values[i][j];
                     if (value == null)
                     {
                         value="";
                     }
                     cellStyle = '<td class="msgTable">';
                     if (j == 0)
                     {
                         cellStyle = '<td class="msgTable segSeq">';
                         //value = datatype + '_' + value;
                         if (isComplexDatatype)
                         {
                             typeElementId = elementId + '_' + datatype + '_' + i;
                             value = '<div id="Cell_' + typeElementId + '" class="expand2" onClick="segToggle(\'' + typeElementId + '\')">\u229e<\/div>' + value;
                         }
                     }
                     else if ( (j > 1) && (j < 6) )
                     {
                         cellStyle = '<td class="msgTable col' + j + '">';
                     }
                     else if (j == 6 )
                     { 
                         value = value.replace(/(?:\r\n|\r|\n)/g, '<br />');
                     }
                     result = result + cellStyle + value + '<\/td>\n';
                 }
                 result = result + '<\/tr>\n';
                 if (isComplexDatatype)           //build the dataype table
                 {
                     result = result + '<tr id="' + typeElementId + '" class="hide"><\/tr>\n';
                     storeDatatype(types, datatype, typeElementId);
                 }
             }
             result = result + '<\/table>\n<\/td>\n';
             var row = document.getElementById(elementId);
             row.innerHTML = result;
             getDatatypes(types, 1);
         
         }
         function _setSegHeader(values) {
             var content='<tr>\n';
             for (var j=0; j < values[1].length; j++)
             {
                 content = content + '<th class="msgTable segCol' + j + '">' + values[1][j] + '<\/th>\n';
             }
             content = content + '<\/tr>\n';
             return content;
         }
//]]>
</script>