/***************************************************************************
 *                          Zanoza Modeler v2.x                            *
 *      This is unpublished propietary source code of Zanoza Software.     *
 *      The copyright notice does not evidence any actual or intended      *
 *                    publication of such source code.                     *
 *                                                                         *
 *                Copyright (c) 2002-2006 Zanoza Software.                 *
 *                                                                         *
 *                        All rights reserved.                             *
 ***************************************************************************
 *--------------------------------------------------------------------------
 * @author:   Oleg M.
 *--------------------------------------------------------------------------
 * @purpose:  ZModeler 2.x SDK java script utils
 *--------------------------------------------------------------------------
 * @histroy: 31.10.2006. Created
 * @histroy: Grabbed some code from DirectX 7 SDK help file;
 *           (c) Microsoft Corporation'1999.
 */


window.onload = bodyOnLoad;

function bodyOnClick()
{
  var elem = window.event.srcElement;
  for (; elem; elem = elem.parentElement) 
  {
    if (elem.id == "reftip")
      return;
  }

  hideTip();
}


function bodyOnLoad()
{
  //--------add bar;
  if (document.title != "")
    document.body.insertAdjacentHTML("AfterBegin", 
      "<table class='barshade' cellspacing=0><td><i><b>ZM</b>odeler2 SDK:</i> <b>"+document.title+"</b></td></table><br>");
  //--------add footer;
  document.body.insertAdjacentHTML("BeforeEnd", 
    "<span class='footer'>November'2008. Revision 1.2 for ZModeler 2.2.0</span>");

  var Ps;
  var iP = 0;
  Ps = document.all.tags("P");
  for (iP = 0; iP < Ps.length; iP++)
    Ps[iP].innerHTML = "&nbsp;&nbsp;&nbsp;&nbsp;"+Ps[iP].innerHTML;
  Ps = document.all.tags("DL");
  for (iP = 0; iP < Ps.length; iP++)
    Ps[iP].innerHTML = "&nbsp;&nbsp;&nbsp;&nbsp;"+Ps[iP].innerHTML;
  Ps = document.all.tags("DD");
  for (iP = 0; iP < Ps.length; iP++)
    Ps[iP].innerHTML = "&nbsp;&nbsp;&nbsp;&nbsp;"+Ps[iP].innerHTML;

  //--------format code and syntax
  Ps = document.all.tags("PRE");
  for (iP = 0; iP < Ps.length; iP++)
    if ((Ps[iP].className == "syntax") || (Ps[iP].className == "code") || (Ps[iP].className == "expand"))
      Ps[iP].outerHTML = FormatCode(Ps[iP].outerHTML);
  Ps = document.all.tags("P");
  for (iP = 0; iP < Ps.length; iP++)
    if ((Ps[iP].className == "syntax") || (Ps[iP].className == "code"))
      Ps[iP].innerHTML = FormatCode(Ps[iP].innerHTML);
  Ps = document.all.tags("SPAN");
  for (iP = 0; iP < Ps.length; iP++)
    if ((Ps[iP].className == "syntax") || (Ps[iP].className == "code"))
      Ps[iP].innerHTML = FormatCode(Ps[iP].innerHTML);
  Ps = document.all.tags("H3");
  for (iP = 0; iP < Ps.length; iP++)
    if ((Ps[iP].className == "syntax") || (Ps[iP].className == "code"))
      Ps[iP].innerHTML = FormatCode(Ps[iP].innerHTML);
  Ps = document.all.tags("TD");
  for (iP = 0; iP < Ps.length; iP++)
    if ((Ps[iP].className == "syntax") || (Ps[iP].className == "code"))
      Ps[iP].innerHTML = FormatCode(Ps[iP].innerHTML);

  initReftips("PRE");
  initReftips("H3");
  //--------initExpanding blocks
  initExpand("PRE");
  document.body.onclick = bodyOnClick;
}

//--------------------------------------------
// Reftips:parameter popups (c)Microsoft'1999
//--------------------------------------------
function initReftips(tagname)
{
  var DLs = document.all.tags("DL");
  var PREs = document.all.tags(tagname);
  if (DLs && PREs) {
    var iDL = 0;
    var iPRE = 0;
    var iSyntax = -1;
    for (var iPRE = 0; iPRE < PREs.length; iPRE++) {
      if ((PREs[iPRE].className == "syntax") ||
        (PREs[iPRE].className == "terms"))
      {
        while (iDL < DLs.length && DLs[iDL].sourceIndex < PREs[iPRE].sourceIndex)
          iDL++;      
        if (iDL < DLs.length) {
          initSyntax(PREs[iPRE], DLs[iDL]);
          iSyntax = iPRE;
        }
        else
          break;
      }
    }

    if (iSyntax >= 0) {
      var last = PREs[iSyntax];
      last.insertAdjacentHTML(
        'AfterEnd',
        '<DIV ID=reftip CLASS=reftip STYLE="position:absolute;visibility:hidden;overflow:visible;"></DIV>'
        );
    }
  }
}

//
// initializes expand blocks properly;
//
function initExpand(tagname)
{
  var colors = new Array("#cad8f0","#dae4f8","#d0def4","#dee8fa");//"#F4EEE0", "#E0F4E0", "#E0E8F0", "#F0E8FF");
  tags = document.all.tags(tagname);
  var va = 0;
  for (vi = 0; vi < tags.length; vi++) 
    if (tags[vi].className == "expand")
    {
      //format properly;
      var str = tags[vi].outerHTML;
      var pos1 = str.indexOf(".off", 0);
      var pos2 = str.indexOf(".on", 0);
      strInsert = " onClick=\"codeExpandClick(this);\" style=\"cursor: hand; background="+colors[(va>>1)%colors.length]+"; display:";
      if (pos1 > 0)
      {
        strInsert = strInsert + "\"";
        str = str.substr(0, pos1+5) + strInsert + ";" + str.substr(pos1+5, str.length);
      }
      else
      if (pos2 > 0)
      {
        strInsert = strInsert + "none;\"";
        str = str.substr(0, pos2+4) + strInsert + ";" + str.substr(pos2+4, str.length);
      }
      else
        continue;
      //window.alert(str);
      tags[vi].outerHTML = str;
      va++;
    }
}

function initSyntax(pre, dl)
{
  var strSyn = pre.outerHTML;
  var ichStart = strSyn.indexOf('>', 0) + 1;
  var terms = dl.children.tags("DT");
  if (terms)
  {
    if (pre.className == "syntax")//per-word search
    for (var iTerm = 0; iTerm < terms.length; iTerm++)
    {
      var words = terms[iTerm].innerText.replace(/\[.+\]/g, " ").replace(/,/g, " ").split(" ");
      var htm = terms[iTerm].innerHTML;
      for (var iWord = 0; iWord < words.length; iWord++) {
        var word = words[iWord];

        if (word.length > 0 && htm.indexOf(word, 0) < 0)
          word = word.replace(/:.+/, "");

        if (word.length > 0) {
          var ichMatch = findTerm(strSyn, ichStart, word);
          while (ichMatch > 0)
          {
            var strTag = '<A HREF="" ONCLICK="showTip(this)" CLASS="synParam">' + word + '</A>';

            strSyn =
              strSyn.slice(0, ichMatch) +
              strTag +
              strSyn.slice(ichMatch + word.length);

            ichMatch = findTerm(strSyn, ichMatch + strTag.length, word);
          }
        }
      }
    }
    if (pre.className == "terms")//per-line search
    for (var iTerm = 0; iTerm < terms.length; iTerm++)
    {
      if ((ichStart = strSyn.indexOf(terms[iTerm].innerText.substr(0, terms[iTerm].innerText.length-1))) >=0)
      {
        var strTag = '<A HREF="" ONCLICK="showTip(this)" CLASS="synParam">' + terms[iTerm].innerText + '</A>';
        strSyn =
          strSyn.slice(0, ichStart) +
          strTag +
          strSyn.slice(ichStart + terms[iTerm].innerText.length);
      }
    }
  }

  // Replace the syntax block with our modified version.
  pre.outerHTML = strSyn;
}

function findTerm(strSyn, ichPos, strTerm)
{
  var ichMatch = strSyn.indexOf(strTerm, ichPos);
  while (ichMatch >= 0) {
    var prev = (ichMatch == 0) ? '\0' : strSyn.charAt(ichMatch - 1);
    var next = strSyn.charAt(ichMatch + strTerm.length);
    if (!isalnum(prev) && !isalnum(next) && !isInTag(strSyn, ichMatch)) {
      var ichComment = strSyn.indexOf("/*", ichPos);
      while (ichComment >= 0) {
        if (ichComment > ichMatch) {
          ichComment = -1;
          break; 
        }
        var ichEnd = strSyn.indexOf("*/", ichComment);
        if (ichEnd < 0 || ichEnd > ichMatch)
          break;
        ichComment = strSyn.indexOf("/*", ichEnd);
      }
      if (ichComment < 0) {
        ichComment = strSyn.indexOf("//", ichPos);
        while (ichComment >= 0) {
          if (ichComment > ichMatch) {
            ichComment = -1;
            break; 
          }
          var ichEnd = strSyn.indexOf("\n", ichComment);
          if (ichEnd < 0 || ichEnd > ichMatch)
            break;
          ichComment = strSyn.indexOf("//", ichEnd);
        }
      }
      if (ichComment < 0)
        break;
    }
    ichMatch = strSyn.indexOf(strTerm, ichMatch + strTerm.length);
  }
  return ichMatch;
}

function isInTag(strHtml, ichPos)
{
  return  (strHtml.lastIndexOf('<', ichPos) >
        strHtml.lastIndexOf('>', ichPos)) ||
      (strHtml.lastIndexOf("/*", ichPos) >
        strHtml.lastIndexOf("*/", ichPos));
}

function isalnum(ch)
{
  return ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || (ch == '_'));
}

function showTip(link)
{
  bodyOnClick();

  var tip = document.all.reftip;
  if (!tip || !link)
    return;

  window.event.returnValue = false;
  window.event.cancelBubble = true;


  // Hide the tip if necessary and initialize its size.
  tip.style.visibility = "hidden";
  tip.style.pixelWidth = 260;
  tip.style.pixelHeight = 24;

  // Find the link target.
  var term = null;
  var def = null;
  var DLs = document.all.tags("DL");
  for (var iDL = 0; iDL < DLs.length; iDL++) {
    if (DLs[iDL].sourceIndex > link.sourceIndex) {
      var dl = DLs[iDL];
      var iMax = dl.children.length - 1;
      for (var iElem = 0; iElem < iMax; iElem++) {
        var dt = dl.children[iElem];
        if (dt.tagName == "DT" && dt.style.display != "none") {
          if (findTerm(dt.innerText, 0, link.innerText) >= 0) {
            var dd = dl.children[iElem + 1];
            if (dd.tagName == "DD") {
              term = dt;
              def = dd;
            }
            break;
          }
        }
      }
      break;
    }
  }

  if (def)
  {
    window.linkElement = link;
    window.linkTarget = term;
    tip.innerHTML = '<DL style=\"background:#e0f0ff;margin:0px;padding:0px;\"><DT style=\"background:#99ccff!important; padding-left:10px; margin-right:0px;font-weight:bold;\">'
      + term.innerHTML +
      '</DT><DD style=\"background:#e0f0ff!important; padding:5px;margin-left:0px; margin-right:5px;\">' + def.innerHTML + '</DD></DL>';
    window.setTimeout("moveTip()", 0);
  }
}

function moveTip()
{
  var tip = document.all.reftip;
  var link = window.linkElement;
  if (!tip || !link)
    return; //error

  var w = tip.offsetWidth;
  var h = tip.offsetHeight;

  if (w > tip.style.pixelWidth) {
    tip.style.pixelWidth = w;
    window.setTimeout("moveTip()", 0);
    return;
  }

  var maxw = document.body.clientWidth;
  var maxh = document.body.clientHeight;

  if (h > maxh) {
    if (w < maxw) {
      w = w * 3 / 2;
      tip.style.pixelWidth = (w < maxw) ? w : maxw;
      window.setTimeout("moveTip()", 0);
      return;
    }
  }

  var x,y;

  var linkLeft = link.offsetLeft - document.body.scrollLeft;
  var linkRight = linkLeft + link.offsetWidth;

  var linkTop = link.offsetTop - document.body.scrollTop;
  var linkBottom = linkTop + link.offsetHeight;

  var cxMin = link.offsetWidth - 24;
  if (cxMin < 16)
    cxMin = 16;

  if (linkLeft + cxMin + w <= maxw) {
    x = maxw - w;
    if (x > linkRight + 8)
      x = linkRight + 8;
    y = maxh - h;
    if (y > linkTop)
      y = linkTop;
  }
  else if (linkBottom + h <= maxh) {
    x = maxw - w;
    if (x < 0)
      x = 0;
    y = linkBottom;
  }
  else if (w <= linkRight - cxMin) {
    x = linkLeft - w - 8;
    if (x < 0)
      x = 0;
    y = maxh - h;
    if (y > linkTop)
      y = linkTop;
  }
  else if (h <= linkTop) {
    x = maxw - w;
    if (x < 0)
      x = 0;
    y = linkTop - h;
  }
  else if (w >= maxw) {
    x = 0;
    y = linkBottom;
  }
  else {
    w = w * 3 / 2;
    tip.style.pixelWidth = (w < maxw) ? w : maxw;
    window.setTimeout("moveTip()", 0);
    return;
  }

  link.style.background = "#FFFF80";
  tip.style.pixelLeft = x + document.body.scrollLeft;
  tip.style.pixelTop = y + document.body.scrollTop;
  tip.style.visibility = "visible";
}

function hideTip()
{
  if (window.linkElement)
  {
    window.linkElement.style.background = "";
    window.linkElement = null;
  }

  var tip = document.all.reftip;
  if (tip)
  {
    tip.style.visibility = "hidden";
    tip.innerHTML = "";
  }
}

function codeExpandClick(item)
{
  strName = "";
  if (item.name.indexOf(".off") >= 0)
    strName = item.name.substr(0, item.name.length-4) + ".on";
  else
    strName = item.name.substr(0, item.name.length-3) + ".off";

  var Atags = document.all.tags("PRE");
  for (var iA = 0; iA < Atags.length; iA++) 
    if (Atags[iA].name == strName)
    {
      item.style.display = "none";
      Atags[iA].style.display = "";
      return;
    }
}


function BuildHierarchyChart(chart)
{//chart is ["ZUnknown", "IService", "ISomeService"]
  var i;
  var code = "<div style=\"height: "+(10+ chart.length*32)+"px; overflow:hidden;\">";
  var table;
  for (i = 0; i < chart.length; i++)
  {
    table = 
    "<div style=\""+
      "width:140px;"+
      "height:22px;"+
      "border: 2 outset #cef;"+
      "background: #9cf;"+
      "position:relative;"+
      "left:"+(i+1)*20+"px;"+
      "top:-"+(i*20)+"px;"+
      "text-align:center;"+
      "z-index:1;"+
      "cursor:hand;"+
      "\"><a style=\"width:100%;\" href=\"../"+chart[i]+"/overview.html\"><b>"+chart[i]+"</b></a></div>\r\n";
    if (i < chart.length-1)
      table+="<div style=\"position:relative; border-left:1 solid black; border-bottom:1 solid black; left:"+(30+(i*20))+"px; top:-"+(i*20+10)+"px; width:40; height:30;z-index:0;\"></div>"
    code+=table;
  }
  code+="</div>";
  document.body.insertAdjacentHTML("AfterBegin", code);
}

//---------------------------------------
// ZModeler SDK code:
//---------------------------------------
var Boldalize = [
  "#include",
  "#define",

  "bool",
  "break",
  "BYTE",

  "CALLBACK",
  "case",
  "CDC",
  "CFont",
  "char",
  "class",
  "const",
  "continue",
  "CDialog",
  "CWnd",

  "delete",
  "do",
  "double",
  "DWORD",

  "else",
  "enum",
  "extern",

  "false",
  "float",
  "for",
  "friend",

  "HINSTANCE",
  "HWND",

  "if",
  "inline",
  "int",

  "long",
  "LPCTSTR",
  "LPTSTR",

  "namespace",
  "new",
  "NULL",

  "operator",

  "private",
  "protected",
  "public",

  "return",

  "short",
  "signed",
  "sizeof",
  "static",
  "static_cast",
  "struct",
  "switch",

  "this",
  "typedef",
  "true",

  "union",
  "unsigned",
  "using",

  "virtual",
  "void",

  "while",
  "WORD",

  "ZAngle",
  //ZAPICALL
  "ZBlackBox",
  "ZBoundary",
  "ZIntrCollection",
  "ZCollection",
  "ZColor",
  "ZEntityBase",
  "ZLine",
  "ZLine3D",
  "ZMatrix",
  "ZOpaque",
  "ZPlane",
  "ZPoint",
  "ZPoint2D",
  "ZPoint3D",
  "ZPoly",
  "ZPolyBuf",
  "ZPtr",
  "ZQuatern",
  "ZRect",
  "ZRESULT",
  "ZSequence",
  "ZString",
  "ZStringSeq",
  "ZUnknown",
  "ZVector",
  "ZVertex",
  "ZVertexBuf",
  ];

function FormatCode(str)//Source)
{
  //var str = Source.outerHTML;
  
  //comments;
  pos = 0;
  while ((pos = str.indexOf("//", pos)) >= 0)
  {
    var prev = str.substr(0,pos);
    var next = str.substr(pos, str.length - pos);
    if ((pos = next.indexOf("\r\n", 0)) >=0 )
      next = next.substr(0,pos)+"</font>"+next.substr(pos,next.length-pos);
    else
      next = next+"</font>";
    pos = prev.length+24;
    str = prev+"<font color=\"#008000\">"+next;
  }
  pos = 0;
  while ((pos = str.indexOf("/*", pos)) >= 0)
  {
    var prev = str.substr(0,pos);
    var next = str.substr(pos, str.length - pos);
    pos = next.indexOf("*/", 0);
    if (pos >=0)
    {
      next = next.substr(0,pos+2)+"</font>"+next.substr(pos+2,next.length-pos-2);
      pos = prev.length+24;
    }
    else
      pos = str.length;
    str = prev+"<font color=darkgreen>"+next;
  }

  //strings;
  pos = 0;
  while ((pos = str.indexOf("\"", pos)) >= 0)
  {
    var prev = str.substr(0,pos);
    var next = str.substr(pos+1, str.length - pos - 1);
    var pos2=0;
    while (((pos2 = next.indexOf("\"",pos2))>=0) && (next.charAt(pos2-1) == "\\"))
      pos2++;
    if (!isInTag(str, pos) &&            //skip if in tag
      (str.charAt(pos-1) != "\\") &&
      (prev.lastIndexOf("//", pos) <=
        prev.lastIndexOf("\r\n", pos)) &&
      !isInTag(next, pos2) &&            //skip if in tag
      (next.lastIndexOf("//", pos2) <=
        next.lastIndexOf("\r\n", pos2)))
    {
      str = prev + "<font color=darkred>\""+next.substring(0, pos2+1)+"</font>"+
        next.substr(pos2+1, next.length-pos2-1);
      pos += 21+(pos2+1)+7;
    }
    else
      pos++;//move from this match;
  }
  pos = 0;
  while ((pos = str.indexOf("&lt;", pos)) >= 0)
  {
    var prev = str.substr(0,pos);
    var next = str.substr(pos, str.length - pos);
    var pos2 = next.indexOf("&gt;\r\n",0);
    if ((pos2 != -1 && pos2 < next.indexOf("\n",0)) &&
      next.substr(4, 1) != " " && //&lt; must not follow by "space"
      !isInTag(str, pos) &&            //skip if in tag
      (str.charAt(pos-1) != "\\") &&
      (prev.lastIndexOf("//", pos) <=
          prev.lastIndexOf("\r\n", pos)) &&
      !isInTag(next, pos2) &&            //skip if in tag
      (next.lastIndexOf("//", pos2) <=
        next.lastIndexOf("\r\n", pos2)))
    {
      str = prev + "<font color=darkred>&lt;"+next.substring(4, pos2+4)+"</font>"+
        next.substr(pos2+4, next.length);
      pos += 21+(pos2+3)+7;
    }
    else
      pos++;//move from this match;
  }

  //boldalise;
  for (var i = 0; i < Boldalize.length; i++)
  {
    pos = 0;
    while ((pos = str.indexOf(Boldalize[i], pos)) >= 0)
    {
      var prev = str.substr(0,pos);
      var next = str.substr(pos+(Boldalize[i].length), str.length - pos - Boldalize[i].length);
      if (!isInTag(str, pos) &&            //skip if in tag
        !isalnum(str.charAt(pos-1)) &&        //skip inside other words
        (prev.lastIndexOf("<font color=darkred>\"", pos) <=
          prev.lastIndexOf("\"</font>", pos)) &&  // inside of the string
        (prev.lastIndexOf("<font color=darkred>&lt;", pos) <=
          prev.lastIndexOf("&gt;</font>", pos)) &&  // inside of the string
        !isalnum(str.charAt(pos+Boldalize[i].length)) &&
        (prev.lastIndexOf("//", pos) <=
          prev.lastIndexOf("\r\n", pos))) //comment
      {
        str = prev + "<b><font color=darkblue>"+Boldalize[i]+"</font></b>" + next;
        pos +=Boldalize[i].length+3+21+7+4;
      }
      else
        pos++;//move from this match;
    }
  }
  //Source.outerHTML = str;
  return str;
}


