//pagelib.js
/* WEBPAGE USING THIS LIBRARY
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="content-type" content="text/html; charset=windows-1250">
<title>dummy</title>
<script type="text/javascript" src="common/pagelib.js"></script>
<script type="text/javascript">
writeStyle();
</script>
</head><body>
<div class="c_main" id="main" onmousemove="mainmousemove()">
----------MAIN CONTENT REPLACES THIS LINE-----------
</div>
<script type="text/javascript">
makePage();
</script>
</body></html>
*/

var PAGELIB_VERSION = "pagelib 003";

//--------------- PAGE CONSTANTS ------------------------
var BROWSER = navigator.appName.toUpperCase();
var MS_EXPLORER = (BROWSER.indexOf("MICROSOFT",0) >= 0);
var BANNERPIC   = 'common/banner15.jpg';
var PAGEWIDTHPX = 900;
var MENUWIDTHPX = 135;//180
var MENU_VERT_INC  = 21;
var MENU_HORZ_INC = MENUWIDTHPX - 5;//175;
var MENUITEMHEIGHTPX = 19;
var PAGETOPPX   = 5;
var PAGELEFTPX  = 5;
var BANNERHTPX  = 80;
var GAPPX       = 0;

var MENU_BORDER_COL     = '#ffffff';
var MENUBACKGROUND      = '#bd6';//#ffe0d0';
var MENU_HOVER_COLOR    = '#892';//#b09080';
var MENU_FONT_SIZE      = '12px';
var MENU_FONT           = 'font-family:Helvetica,Arial,sans-serif;font-weight:normal;font-style:normal;'
var MENU_FONT_COLOR     = '#404040';
var MENU_ARROW_IMG      = 'common/arrow.gif';
var USE_MENU_ARROW      = true;//else use "..."

var CRLF = "\n";

var MAINWIDTHPX = PAGEWIDTHPX - MENUWIDTHPX - GAPPX;

var PAGEWIDTH = "width:" + PAGEWIDTHPX + "px;";
var PAGETOP   = "top:" + PAGETOPPX + "px;"
var PAGELEFT  = "left:" + PAGELEFTPX + "px;"

var MENUTOP   = "top:" + (PAGETOPPX + BANNERHTPX + GAPPX + 10)  + "px;";
var MENULEFT  = PAGELEFT;
var MENUWIDTH = "width:" + MENUWIDTHPX + "px;"; //MENUWIDTH = "";

var MAINLEFT  = "left:" + (PAGELEFTPX + MENUWIDTHPX + GAPPX) + "px;";
var MAINTOP   = "top:" + (PAGETOPPX + BANNERHTPX + GAPPX)  + "px;";
var MAINWIDTH = "width:" + (PAGEWIDTHPX - MENUWIDTHPX - GAPPX) + "px;"; //MAINWIDTH = "";

var BORDER    = 'border:1px #4040c0 solid;'; BORDER="border:1px #ffffff solid;";
var LINKCOLOR = "color:#303080;";
var FONTCOLOR = "color:#333;";
var HEADCOLOR = "color:#3030a0;";
var FONTSIZE  = "font-size:13px;";

var DIVIDER = '<div style="font-size:1px;border-top:solid;border-width:1px;border-color:#4040c0;width:100%;height:1px;margin:4px 0px 3px 0px;"></div>';
var BLANKLINE = '<div style="height:12px;"></div>\n';
var MENU_HORIZ_OFFSET = 6;
var SPECIFIC_MARGINS = "margin:0px 0px 0px 0px;padding:1px 0px 1px 5px;";
if (MS_EXPLORER)
    {
    MENU_HORIZ_OFFSET = 0;
//    SPECIFIC_MARGINS = "margin:0px 0px 0px 0px;padding:2px 0px 2px 5px;";
    SPECIFIC_MARGINS = "margin:0px 0px 0px 0px;padding:3px 0px 3px 5px;";
    }


//---------- MENU CONSTANTS ----------------
var CRLF = "\u000A";
var QUOTE = "'";
var UNQUOTE = QUOTE;
var COLUMN_MENU = 1;
var TAB_MENU = 2;
var ON_BANNER = -1;//must aagree with html
var ON_MAIN = -2;//must aagree with html
var ON_GUARD_AREA = -3;
var EDIT_MENU = false;
var DEFAULTDOC = "dummy.html";
var NMOUSECHECK = 8;

//------------ MENU VARIABLES ------------------
var MAXM;   //size of array reserved for menu items
var mItems; //number of menu items
var mIndex; //pointer
var nBranch;//number of branches
var nLeaf;  //number of leaves
var mPar = new Array();   //array parent, -1 if none
var mSib = new Array();   //array next sibling, -1 if no more
var mChi = new Array();   //array first child, -1 if none or a leaf
var mTxt = new Array();   //array text to show
var mJmp = new Array();   //array url
var mcList = new Array(); //array
var menuTarget; //where menu is to be written
var writtenMenuIndex=-103; //index used to write currently showing menu
var menuStr="";
var diagStr="";
var writing=false;
var mmHandling=false;
var mcPntr;
var mcList;
var menuType;





//-------------- PAGE FUNCTIONS ----------------------

//margin-border-padding-CONTENT-padding-border-margin
//This write the CSS <style>...</style> stuff
function styleStr()
{
var t = ""
+'<style type="text/css">\n'
+'body{font-family:arial; ' + FONTCOLOR + ';' + FONTSIZE + '}\n\n'
+'p{' + FONTSIZE + FONTCOLOR + 'margin:5px 5px 7px 5px;}\n\n'
+'pre{font-family:courier new,fixed;' + FONTSIZE + 'color:#000000;margin:0px 0px 0px 0px}\n\n'
+'i{font-weight:normal;}\n\n'
+'em{font-weight:bold;font-style:normal;}\n\n'
+'.c_copyright{font-size:10px;font-style:italic;color:#6060ff;text-align:right;margin:0px 5px 0px 5px}\n\n'
+'.c_discrete{font-size:11px;font-style:italic;color:#6060ff;margin:0px 5px 0px 5px}\n\n'
+'.c_a{font-weight:normal;color:#777}\n\n'
//+'.c_img{border:2px solid black;}\n'
+'.c_img{}\n\n'
+'.c_banner{position:absolute;' + PAGETOP + PAGELEFT + PAGEWIDTH + '}\n\n'
+'.c_main{position:absolute;' + MAINLEFT + MAINTOP + MAINWIDTH + BORDER + '}\n\n'
+'.c_menu{position:absolute;' + MENULEFT + MENUTOP + MENUWIDTH + ';background-color:#ffffff;z-index:99;}\n\n'
+'#menuid p{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;background-color:#4040ff;}\n\n'
+'#menuid a{' + MENU_FONT + ';' + 'font-size:' + MENU_FONT_SIZE + ';\n'
+'  text-decoration:none;color:' + MENU_FONT_COLOR + ';width:' + (MENU_HORZ_INC-MENU_HORIZ_OFFSET) + 'px;\n'
+'  display:block;height:' + MENUITEMHEIGHTPX + 'px;\n'
+'  background-color:' + MENUBACKGROUND + ';'
+'  border:solid;border-width:1px;border-color:' + MENU_BORDER_COL + ';\n'
+'  ' + SPECIFIC_MARGINS + '\n'
+ '}\n\n'
//+'#menuid a:hover{background-color:#6060ff;color:white;}\n\n'
+'#menuid a:hover{background-color:' + MENU_HOVER_COLOR + ';color:white;}\n\n';

if (USE_MENU_ARROW)
    {
    t += 'a.branch{background-image:url("' + MENU_ARROW_IMG + '");background-position:right;background-repeat:no-repeat;}\n\n'
    + '#menuid a.mainpath{background-color:'+ MENU_HOVER_COLOR +';color:white;background-image:url("' + MENU_ARROW_IMG + '");\n'
    +'  background-position:right;background-repeat:no-repeat;}\n\n';
    }

t += 'h1,h2,h3,h4,h5,h6{' + HEADCOLOR + 'font-style:italic;margin:5px 0px 0px 5px}\n\n'
+'h1{font-size:25px;}h2{font-size:18px;}h3{font-size:16px;}\n'
+'h4{font-size:14px;}h5{font-size:13px;}h6{font-size:12px;}\n\n'
+'a{' + FONTSIZE + 'text-align:left;font-weight:normal;text-decoration:underline;\n'
+'color:#000000;margin-left:0px;' + LINKCOLOR + '}\n\n'
+'a:link {} a:visited {} a:hover{text-decoration:underline; color:#000000;background:#ff8080;} a:active {}\n\n'
+'ul{margin-top:-2px;list-style-type:circle;}\n\n'
+'li {' + FONTSIZE + 'color:#404040;margin:5px 5px 5px 15px}\n\n'
+'</style>\n';
return t;
}

function writeStyle()
{
document.write(styleStr());
}

//function item(url,txt){return "<a class='c_a' href='"+url+"'>" + txt + "</a><br>\n";}

function dummy(){alert("This page is not implemented yet...");}


//var BANNERDIV = '<div id="bannerid" style="position:absolute;' + PAGETOP + PAGELEFT + PAGEWIDTH + '" onmousemove="bannermousemove()"><img src= "' + BANNERPIC + '"></div>\n';

//var MENUDIV = '<div class="c_menu" id="menuid"></div>';
//<div class="c_menu" name = "menuid" id="menuid" style="position:absolute;left:5px;top:90px;width:180px;"></div>;


//use in mouse areas where base menu is to be redrawn
function mainmousemove(){mousemove(0);}
function bannermousemove(){mousemove(0);}


function makePage()
{
document.getElementById("bannerid").innerHTML= '<img src= "' + BANNERPIC + '">';
initMenu();
}


function showLiterally(txt)
{
txt = txt.replace(/</g,"&lt;");
txt = txt.replace(/>/g,"&gt;");
var w = 800;
var h = 600;
var tp = (screen.height - h)/2;
var lf = (screen.width - w)/2;
var format="top=" + tp + ",left=" + lf + ",width=" + w + ",height=" + h + ", resizable=1, scrollbars=1, menubar=0, toolbar=0";
var win2 = window.open("","",format);
if (win2 == null) alert("cannot open new window");
var T = "<html><head></head>"
 + "\n<body>\n"
 + "<pre style='font-size:12px;color:#000000;background:#ffffc0'>" + txt + "</pre>"
 + "\n<script>self.focus();<\/script>"
 + "\n<\/body><\/html>";
win2.document.write(T);
win2.document.close();
}//showLiterally



function showPrintVersion()
{
var h = 600;
var w = 900;
var tp = (screen.height - h)/2;
var lf = (screen.width - w)/2;
var format="top=" + tp + ",left=" + lf + ",width=" + w + ",height=" + h + ", resizable=1, scrollbars=1, menubar=1, toolbar=1";
var win2 = window.open("","",format);
if (win2 == null) alert("cannot open new window");
//var s = document.getElementById("main").innerHTML;
var T = "<html><head>"
 + styleStr() + "\n"
 + "</head>"
 + "\n<body>\n"
 + removeHref(document.getElementById("main").innerHTML)
 //+ document.getElementById("main").innerHTML;
 + "\n<script>self.focus();<\/script>"
 + "\n<\/body><\/html>";
win2.document.write(T);
win2.document.close();
}//showLiterally



function browserStr()
{
var browser=navigator.appName;
var full_version=navigator.appVersion;
var version=parseFloat(full_version);
var IE = "NOT IE";
if (MS_EXPLORER) IE = "IE";
return "["+browser + "] [" + version + "] [" + full_version + "]" + " IE=" + IE;
}


function showSoftwareDetails()
{
var s = "Document details:"
 +"\nPAGELIB_VERSION=" + PAGELIB_VERSION
 +"\nMAINWIDTHPX=" + MAINWIDTHPX
 +"\nPAGEWIDTHPX=" + PAGEWIDTHPX
 +"\nMENUWIDTHPX=" + MENUWIDTHPX
alert(s);
}

//---------------- MENU FUNCTIONS -------------------
function initMenu()
{
if (EDIT_MENU)
  {
  DEFAULT_DOC = "javascript:dummy()"
  QUOTE = UNQUOTE = '"';
  }
menuType = COLUMN_MENU;
//menuType = TAB_MENU;
mcList = new Array(NMOUSECHECK);for (var j=0;j<NMOUSECHECK;j++) mcList[j] = -500;
mcPntr = 0;
mmHandling=false;
writing=false;
buildMenuTree(menu1);
menuTarget=document.getElementById("menuid");
writeMenu(0);
}


//very short function 'cos it's called by tiniest mouse movement
function mousemove(node)
{
if (mmHandling) return;
mmHandling = true;
mcList[mcPntr] = node;
mcPntr = (1 + mcPntr) % NMOUSECHECK;
if (node <= 0){for (var j=0;j<NMOUSECHECK;j++) if (mcList[j]!=node) {mmHandling=false;return;}}
writeMenu(node);
mmHandling = false;
}


//buildMenuTree(menu1) builds tree from menu1[] by depth-first search
//do this before anything else
function buildMenuTree(m)
{
var L = m.length;
MAXM=1;for (var j=0;j<L;j++) if (m[j].charAt(0) != "<") MAXM++;

if (EDIT_MENU) MAXM += 1000;
mPar = new Array(MAXM);  //parent, -1 if none
mSib = new Array(MAXM);  //next sibling, -1 if no more
mChi = new Array(MAXM);  //first child, -1 if none or a leaf
mTxt = new Array(MAXM);  //text to show
mJmp = new Array(MAXM);  //url

var nxt,j,par,chi;
writing=false;
writtenMenuIndex=-2;
//zeroize tree components
for (j=0;j<MAXM;j++)
  {
  mPar[j] = mSib[j] = mChi[j] = -1; //no parents, siblings, children
  mJmp[j] = mTxt[j] = "";  //no text or jumps
  }
nBranch=nLeaf=0;

j=0
mTxt[0] = "root";  //this node is not allowed a sibling or a parent
mJmp[0] = "jmp0";
par = 0;  //we are about to fill in the details of a child of this node
nxt = 1;  //the next unallocated node number

while (j < L)//main loop
  {
  ch = m[j].charAt(0);
  while ((ch == "<") && (mPar[par] >= 0) && (j < L)) //backup if necessary
    {
    par = mPar[par];
    j++;
    if (j<L) ch = m[j].charAt(0);
    }
  if (j >= (L-1)) {mItems = nxt;return;}

  //at this point m[j] indicates a forward branch or a sibling
  //find or allocate first child
  chi = mChi[par];
  if (chi < 0)//if no child set nxt as child
    {
    chi = nxt;
    mChi[par] = chi;
    mPar[chi] = par;
    }
  else //set nxt as new sibling
    {
    while (mSib[chi] >= 0) chi = mSib[chi]; //put chi = last child of parent
    mSib[chi] = nxt;
    mPar[nxt] = par;
    }

  //fill in details of nxt
  if (ch == ">") //branch
    {
    nBranch++;
    mTxt[nxt] = m[j].substring(1,m[j].length);
    if (!USE_MENU_ARROW) mTxt[nxt] += '<span style="font-weight:bold">...</span>';
    par = nxt;  //move forward
    }
  else //leaf = sibling of mIndex
    {
    nLeaf++;
    var i = m[j].indexOf("|");
    if (i<0){mTxt[nxt] = m[j]; if (!EDIT_MENU) mJmp[nxt]=DEFAULTDOC;}
    else{mTxt[nxt] = m[j].substring(0,i);mJmp[nxt]=m[j].substring(i+1,m[j].length);}
    }
  nxt++;
  j++;
  }//main loop
mItems = nxt;
}//buildMenuTree(m)

//used by writeMenu(k)
//menuItemStr(txt, nChi, k, jmpStr,x,y,ppp)
//creates a string menu entry like
//  <div style='position:absolute;top:200px;left:10;z-index:99;' onmouseover='mouseover(" + k + ")'>
//  <p><a href="index.php" class="leaf">HOME</a><p></div>
function menuItemStr(txt, nChi, k, jmpStr, x, y, ppp)
{
//txt += "/" + k ;
var url,t="";
if (nChi >= 0) //branch
  {
  if (EDIT_MENU) url = "javascript:branchfunc(" + k + ")"; else url = "#";
  if (k == ppp) type = "mainpath"; else type="branch";
  }
else //leaf
  {
  type = "leaf";
  if (EDIT_MENU) url = "javascript:leaffunc(" + k + ")"; //different from main version
  else
    {
    if (jmpStr == "") url = DEFAULTDOC;
    else if (jmpStr.substring(0,2)=="j:") url="javascript:" + jmpStr.substring(2,jmpStr.length);
    else url = jmpStr;
    }
  }
var styleStr = "<div style='position:absolute;top:" + y + "px;left:" + x + "px;"
+ "z-index:99;' onmousemove='mousemove(" + k + ")'";
styleStr += ">"
t += styleStr + "<p><a href=" + QUOTE + url + UNQUOTE + " class=" + QUOTE + type + UNQUOTE;
t += ">" + txt + "</a></p></div>" + CRLF;
return t;
}


//depth into tree of node k, node 0 has depth 0, mChi[0] has depth 1 etc
function nDepth(k){var d=0;while (k>0) {d++; k = mPar[k]}return d;}

//return string specifying all menu buttons for children of parent
//downwards from y pixels = vert posn of parent
//horizontal position determined by depth of parent
function childColumn(parent, y, prevp)
{
if (parent < 0) return;
var i = parent;
var depth = nDepth(parent);
var t = "";
var x = MENU_HORZ_INC*depth;

//write all children of i
var k = mChi[i] //go to first child
while (k >=0)
  {
  t += menuItemStr(mTxt[k], mChi[k], k, mJmp[k], x, y, prevp);
  k = mSib[k];
  y += MENU_VERT_INC;
  }
menuStr += t;
return y;
}


//depthFromRoot(k) returns the vertical depth from top-left menu item of item k
//if node[k] if the n0th child of the n1th child of ... the nMth of the root
//then this returns n0 + n1 + ... + nM
function depthFromRoot(k)
{
var h = 0;
while (k > 0)
  {
  var c = mChi[mPar[k]] //first child of parent
  while (c != k){c = mSib[c];h++;}
  k = mPar[k];
  }
return h;
}

//##write menu backwards from parent node to 0
function writeMenu(parent)
{
if (writing) return;

if (EDIT_MENU)
  {
  if (!menuChanged && (parent == writtenMenuIndex)) return;//different
  menuChanged = false;
  }
else
  {
  if (parent==writtenMenuIndex) return;
  }

writing = true;

var pp = parent;
var prevp = -1;

if (menuType==COLUMN_MENU)
  {
  if (parent < 0) pp = 0;
  }
else if (menuType == TAB_MENU)
  {
  if (parent == ON_BANNER) pp=0;
  else if ((parent == ON_MAIN) || (parent == ON_GUARD_AREA))
    {
    //menuTarget.innerHTML = "";
    writtenMenuIndex = parent;
    writing = false;
    return;
    }
  }

var depth = 0;
var url;
var k;
var y  = 0;

menuStr = "";

//write child column from parent then iterate backwards thru parents to root
while (pp >=0)
  {
  y = childColumn(pp,MENU_VERT_INC*depthFromRoot(pp),prevp);
  prevp = pp;
  pp = mPar[pp];
  }

var guardStr= "<div style='position:absolute;top:" + y + "px;left:0px;"
+ "width:" + MENU_HORZ_INC + "px;height:50px;background-color:#ffffff;'"
+ " onmousemove='mousemove(" + ON_GUARD_AREA + ");'>"
//+ "<p> Hi there</p>"
+ "<p style='font-size:9px;color:#a0a0a0;background-color:#ffffff;margin-top:15px;font-style:italic'>"
+ PAGELIB_VERSION + "</p>"
+"</div>";


menuTarget.innerHTML = menuStr + guardStr;
writtenMenuIndex = parent;
writing = false;
}//writeMenu

function showStats()
{
var s = "This menu has " + mItems + " items, " + nBranch + " branches, " + nLeaf + " leaves and "
+ MAXM + " elements."
+ CRLF + "Library version = " + MENUCODE_VERSION;
alert(s);
}

//replace "<a href='whatever'>" by "<a>" to disable jumps
function removeHref(S)
{
var i,k;
i=0;
var s = S.toLowerCase();
k = s.indexOf("<a",i);
if (k<0) return S;
var ss="";
while (k>=0)
  {
  ss += S.substring(i,k) + "<a>";
  k = s.indexOf(">",k);//skip to next ">"
  i = k+1;
  k = s.indexOf("<a",i);
  }
ss += S.substring(i,s.length);
return ss;
}
