/*------------------------------------------------------------*/
/* File: narrowselection.js                                   */
/* Author: John Bradnam                                       */
/* Date: 03/01/2006                                           */
/* Copyright: Republicorp P/L                                 */
/* Purpose: Provides narrow selection to a HTML edit control  */
/* CSS rules:                                                 */
/*   table.menu {border:2px outset threedhighlight;           */
/*               font-family:tahoma;font-size:8pt;}           */
/*   tr.menu    {color:menutext;background-color:menu;}       */
/*   tr.selected{color:highlighttext;                         */
/*               background-color:highlight;}                 */
/*------------------------------------------------------------*/
	
var oGblPopupMenu = null;
var wGblMenuSelect = 0;
 
/*------------------------------------------------------------*/
/* Function: NarrowSelectionState                             */
/* Usage: <select name="state" size="1"                       */
/*                onpropertychange="NarrowSelectionState();"> */
/*           <option value="aACT">ACT</option>                */
/*           <option value="aNSW" selected>NSW</option>       */
/*           <option value="aNT">NT</option>                  */
/*           <option value="aQLD">QLD</option>                */
/*           <option value="aSA">SA</option>                  */
/*           <option value="aTAS">TAS</option>                */
/*           <option value="aVIC">VIC</option>                */
/*           <option value="aWA">WA</option>                  */
/*        </select>                                           */
/* Notes: Each value must be the name of an array that        */
/*        contains the suburbs for the narrow selection edit  */
/*        control                                             */
/* var aACT = new Array("acton","ainslie","amaroo",...);      */
/* var aNSW = new Array("abbotsbury","abbotsford",...);       */
/* var aNT = new Array("adelaide river","alawa",...);         */
/* var aQLD = new Array("abbeywood","abbotsford",...);        */
/* var aSA = new Array("aberfoyle park","adelaide",...);      */
/* var aTAS = new Array("abbotsham","abels bay",...);         */
/* var aVIC = new Array("abbotsford","abeckett street",...);  */
/* var aWA = new Array("abba river","abbey",...);             */
/*------------------------------------------------------------*/

function NarrowSelectionState(sSuburbId) {
  var oSuburb = document.getElementById(sSuburbId);
  if (oSuburb != null) {
    DestroyPopupMenu();
    oSuburb.value = "";
    oSuburb.focus();
  }
} //NarrowSelectionState
  
/*------------------------------------------------------------*/
/* Function: NarrowSelection                                  */
/* Usage: <input type="text" name="suburb"                    */
/*               onpropertychange="NarrowSelection();"        */
/*               onkeydown="NarrowKeyDown();">                */
/* Notes: The "state" selection control must exist and point  */
/*        to valid arrays of suburbs.                         */
/*------------------------------------------------------------*/

function NarrowSelection(sStateId) {
  var oState = document.getElementById(sStateId);
  if ((oState != null) && (oState.selectedIndex != -1)) {
//  eval("var aTable="+oState.options(oState.selectedIndex).value+";");
    eval("var aTable=a"+oState.options(oState.selectedIndex).innerText+";");
    //aTable contains table of suburbs for narrowing selection
    var oInp = event.srcElement;
    DestroyPopupMenu();
    if (oInp.value.length != 0) {
      var dFirst = FindFirstSelection(aTable,oInp.value);
      if (dFirst != 0) {
        //count items
        var wCount = 1;
	    var dNext = FindNextSelection(aTable,oInp.value,dFirst);
	    while (dNext != 0) {
          wCount = wCount + 1;
	      dNext = FindNextSelection(aTable,oInp.value,dNext);
	    } //while
	    //Display items in popup
	    if ((wCount == 1) && (oInp.value == aTable[dFirst-1]))
	      DestroyPopupMenu();
	    else
	      PopupLinks(aTable,oInp,dFirst,wCount);
	  }
    }
  }
} //NarrowSelection

/*------------------------------------------------------------*/
/* Function: NarrowKeyDown                                    */
/* Usage: <input type="text" name="suburb"                    */
/*               onpropertychange="NarrowSelection();"        */
/*               onkeydown="NarrowKeyDown();">                */
/*------------------------------------------------------------*/

function NarrowKeyDown()
{
  if (oGblPopupMenu != null) {
    var oTbl = oGblPopupMenu.firstChild;
    switch (event.keyCode) {
      case 40:
        if (wGblMenuSelect < oTbl.rows.length) {
          if (wGblMenuSelect == 0) 
            wGblMenuSelect = 1;
          else {
            _LowlightPopupMenu(oTbl.rows(wGblMenuSelect - 1));
            wGblMenuSelect = wGblMenuSelect + 1;
          }
          _HighlightPopupMenu(oTbl.rows(wGblMenuSelect - 1));
        }
        event.returnValue = false;
        break; //Down arrow
        
      case 38:
        if (wGblMenuSelect > 1) {
          _LowlightPopupMenu(oTbl.rows(wGblMenuSelect - 1));
          wGblMenuSelect = wGblMenuSelect - 1;
          _HighlightPopupMenu(oTbl.rows(wGblMenuSelect - 1));
        }
        event.returnValue = false;
        break; //Up arrow
        
      case 13:
        if (wGblMenuSelect != 0)
          _ClickPopupMenu(oTbl.rows(wGblMenuSelect - 1));
        event.returnValue = false;
        break; //Enter key
     } //switch
   }
} //NarrowKeyDown

/*---------------------------------------------------------------------------*/
/* Support functions                                                         */
/*---------------------------------------------------------------------------*/

function FindFirstSelection(aTable,sSuburb) {
  var dBottom = 1;
  var dTop = aTable.length;
  var dMiddle = 0;
  var fFound = false;
  var sTest = "";

  while ((dBottom <= dTop) && (fFound == false)) {
    dMiddle = (dTop + dBottom) >> 1;
	sTest = aTable[dMiddle - 1].substr(0,sSuburb.length).toLowerCase();
	if (sSuburb < sTest)
	  dTop = dMiddle - 1;
	else if (sSuburb > sTest)
	  dBottom = dMiddle + 1;
	else {
	  //step back from this point looking for first match
	  fFound = true;
	  while ((dMiddle != 1) && (fFound == true)) {
        dMiddle = dMiddle - 1;
        sTest = aTable[dMiddle - 1].substr(0,sSuburb.length).toLowerCase();
 	    if (sSuburb != sTest) {
		  fFound = false;
		  dMiddle = dMiddle + 1;
		}
	  } //while
	  fFound = true;
	}
  } //while
  if (fFound == false)
    dMiddle = 0;
  return dMiddle;
} //FindFirstSelection

function FindNextSelection(aTable,sSuburb,dNext) {
  if ((dNext < aTable.length) && (sSuburb == aTable[dNext].substr(0,sSuburb.length).toLowerCase()))
    dNext = dNext + 1;
  else
    dNext = 0;
  return dNext;
} //FindNextSelection

function PopupLinks(aTable,oInp,dFirst,wCount) {
  var oSty       = null;
  var oMnu       = null;
  var oTbl       = null;
  var oRow       = null;
  var oCell      = null;
  var oTxt       = null;
  var wTop       = 0;
  var wBottom    = 0;
  var oBody      = document.body;
//var wMouseX    = 0;
//var wMouseY    = oInp.scrollHeight;
  var wMouseX    = oInp.offsetLeft;
  var wMouseY    = oInp.offsetTop + oInp.scrollHeight;
  var oTest      = oInp;
  var s          = "";
  while (oTest != oBody) {
    oTest        = oTest.parentElement;
	s += oTest.tagName + ", class='" + oTest.className + "', left=" + oTest.offsetLeft + ", top=" + oTest.offsetTop + "\r\n";
    if ((oTest.tagName != "TR") && (oTest.tagName != "FORM") && (oTest.tagName != "PX") &&
		((oTest.tagName != "DIV") || ((oTest.parentElement.tagName != "FORM") && (oTest.parentElement.tagName != "BODY")))) {
      wMouseX      = wMouseX + oTest.offsetLeft;
      wMouseY      = wMouseY + oTest.offsetTop;
    }
  } //while
//alert(s);
  var wMaxWidth  = oBody.clientWidth - wMouseX;
  var wMaxHeight = oBody.clientHeight - wMouseY - 20;
  oMnu                 = document.createElement("div");
  oSty                 = oMnu.style;
  oSty.position        = "absolute";
  oSty.visibility      = "hidden";
  oSty.overflow        = "hidden";
  document.body.appendChild(oMnu);
  oTbl                 = document.createElement("table");
  oMnu.appendChild(oTbl);
  //Add the elements
  oTbl.style.cursor    = "default";
  oTbl.className       = "menu"
  oTbl.setAttribute("cellPadding","0");
  oTbl.setAttribute("cellSpacing","0");
  oTbl.onselectstart = "javascript:return false;"
  dNext                = dFirst;
  for (wIndex = 0;wIndex < wCount;wIndex++) {
    if (oTbl.offsetHeight < wMaxHeight) {
      if (wIndex == 0)
        wTop = 2;
	  else
	    wTop = 1;
	  if ((wIndex + 1) == wCount)
	    wBottom = 2;
	  else
	    wBottom = 1;
      oRow      = oTbl.insertRow(-1);
      oRow.className           = "menu";
      oRow.style.padding       = wTop+"px 10px "+wBottom+"px 10px";
      oRow.setAttribute("value",aTable[dNext-1]);
      oRow.setAttribute("name",oInp.getAttribute("name"));
      oCell                    = oRow.insertCell(-1);
      oMnu.attachEvent("onmouseover",HighlightPopupMenu);
      oMnu.attachEvent("onmouseout",LowlightPopupMenu);
      oMnu.attachEvent("onmousedown",ClickPopupMenu);
      oTxt                     = document.createTextNode(aTable[dNext - 1]);
      oCell.appendChild(oTxt);
      dNext                    = dNext + 1;
    }
  } //for
  //show menu
  oSty.left            = wMouseX;
  oSty.top             = wMouseY;
  oSty.visibility      = "visible";
  //set event to close it
  oGblPopupMenu        = oMnu;
  wGblMenuSelect       = 0;
  document.attachEvent("onmouseup",DestroyPopupMenu);
} //PopupLinks

function DestroyPopupMenu() {
  document.detachEvent("onmouseup",DestroyPopupMenu);
  if (oGblPopupMenu != null) {
    oGblPopupMenu.style.visibility = "hidden";
    oGblPopupMenu.parentNode.removeChild(oGblPopupMenu);
    oGblPopupMenu = null;
    wGblMenuSelect = 0;
  }
} //DestroyPopupMenu

function HighlightPopupMenu() {
  _HighlightPopupMenu(event.srcElement);
} //HighlightPopupMenu
  
function _HighlightPopupMenu(oMnu) {
  if (oMnu.tagName == "TD")
    oMnu = oMnu.parentNode;
  if (oMnu.tagName == "TR")
    oMnu.className = "selected";
} //_HighlightPopupMenu

function LowlightPopupMenu() {
  _LowlightPopupMenu(event.srcElement);
} //LowlightPopupMenu

function _LowlightPopupMenu(oMnu) {
  if (oMnu.tagName == "TD")
    oMnu = oMnu.parentNode;
  if (oMnu.tagName == "TR")
    oMnu.className = "menu";
} //_LowlightPopupMenu

function ClickPopupMenu() {
  _ClickPopupMenu(event.srcElement);
} //ClickPopupMenu

function _ClickPopupMenu(oMnu) {
  if (oMnu.tagName == "TD")
    oMnu = oMnu.parentNode;
  if (oMnu.tagName == "TR") {
    var sValue    = oMnu.getAttribute("value");
    var sName     = oMnu.getAttribute("name");
    var oInp  = document.getElementById(sName);
    if (oInp != null) {
      oInp.value = sValue;
      oInp.focus();
      oInp.select();
      DestroyPopupMenu();
    }
  }
} //_ClickPopupMenu

/*------------------- end of narrowselection.js -----------------------------------*/
