/* ********************************************************************
 * Evertz Single Frame Modular Layout Tools - Web Application
 *
 * Build a frame right before your eyes, using this tool
 *
 */


/* ***** Global Variables ****************************************** */
var page = enclosures[encHash[window.location.pathname.replace(/^.+[\/\\]([^\/\\]+?)(\.(html|php))?$/, "$1")]];
var frame = new Frame(), app = new Application(), dragon = new Dragon();

var preload = new Image(); preload.src = "/img/evertz/evertz.white.32px.png";



/* ****************************************************************************************************************************************
 ******************************************************************************************************************************************
 ******************************************************************************************************************************************
 * Create page
 *
 */
window.onload = function(e) {
  document.body.className = "wait";

	// Attempt to resize the browser window to fit the frame
	if (self.innerWidth) {
	  frameWidth = self.innerWidth;
	  frameHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientWidth) {
	  frameWidth = document.documentElement.clientWidth;
	  frameHeight = document.documentElement.clientHeight;
	} else if (document.body) {
	  frameWidth = document.body.clientWidth;
	  frameHeight = document.body.clientHeight;
	}
	try {
    if ((frameWidth && frameWidth < page.screen[0]) || (frameHeight && frameHeight < page.screen[1]))
      window.resizeTo(page.screen[0], page.screen[1]);
  } catch(e) {}


  // ***** Sort modules ***********************************************
  modules.sort(modSort);
  for (var x = 0; x < modules.length; x++) modHash[modules[x].name] = x;


  // ***** Apply misc event listeners *********************************
  selectDisable(document.getElementById("selector"));

  document.documentElement.onclick = function() {
    if (!app.maccontext) document.getElementById('slotContext').style.visibility = "hidden";
  }
  for (var x = 0, lis = document.getElementById('slotContext').getElementsByTagName('li'); x < lis.length; x++) {
    lis[x].onmouseover = function() { if (this.className != "disabled") this.className = "hover"; }
    lis[x].onmouseout = function() { if (this.className != "disabled") this.className = ""; }
	  for (var y = 0, as = lis[x].getElementsByTagName('a'); y < as.length; y++) {
	    as[y].target = "_blank";
	    as[y].onclick = function() {
	      document.getElementById('slotContext').style.visibility = "hidden";
	      return (this.parentNode.className != "disabled");
	    }
	  }
  }
  var buttons = document.body.getElementsByTagName('div');
  for (var x = 0; x < buttons.length; x++) {
    if (buttons[x].className.match(/button/)) {
      buttons[x].onmousedown = function(e) {
        if (this.className.indexOf("inactive") == -1)
          this.className = ((this.className.indexOf("highlight") > -1) ? "highlight " : "") + "button active";
      }
      buttons[x].onmouseup = buttons[x].onmouseout = function(e) {
        if (this.className.indexOf("inactive") == -1)
          this.className = ((this.className.indexOf("highlight") > -1) ? "highlight " : "") + "button";
      }
    }
  }
  if (document.getElementById('alert_contact')) {
    document.getElementById('alert_contact').onclick = function() {
      alert('For the fastest response time, please include an email address in the Contact Information field');
      return false;
    };
  }


  // ***** Apply frame image event listeners **************************
  frame.image = document.getElementById("plates").getElementsByTagName("img");
  for (var x = frame.image.length - 1, pos; x >= 0; x--) {
    frame.image[x].id = "module" + x;
    if (page.frame == "3700FR") {
      frame.image[x].ptype = "7700";
      frame.image[x].style.height = "316px";
      if (x < 8) {
        frame.image[x].style.left = ((frame.slots - x - 15) * 50) + "px";
        frame.image[x].style.top = "329px";
      } else if (x < 16) {
        frame.image[x].style.left = ((frame.slots - x - 7) * 50) + "px";
      } else {
        frame.image[x].style.left = ((frame.slots - x + 8) * 50) + "px";
        frame.image[x].ptype = "3000";
        frame.image[x].style.height = "645px";
      }
    } else {
      frame.image[x].style.left = ((frame.slots - x - 1) * 50) + "px";
      frame.image[x].ptype = page.type;
    }
    frame.image[x].style.display = "block";
    pos = findPos(frame.image[x]);
    dragon.targets[x] = [pos[0], pos[1], pos[0] + frame.image[x].offsetWidth, pos[1] + frame.image[x].offsetHeight];
    frame.image[x].ondblclick = function(e) { app.selectorDisplay(true); }
    frame.image[x].onmousedown = (function(x) { return function(e) { dragon.claw(e, x); return false; }})(x);
    frame.image[x].onmousemove = function(e) { dragon.drag(e); return false; }
    frame.image[x].onmouseup = function(e) { dragon.drop(e); return false; }
    if (window.opera) {
      frame.image[x].onmousedown = (function(x) { return function(e) {
        e = e || event;
        dragon.claw(e, x);
        e.cancelBubble = true;
        clearTimeout(app.timeout);
        app.timeout = setTimeout(function() { app.maccontext = false; contextMenu(e, x); app.maccontext = true; }, 500);
        return false;
      }})(x);
      frame.image[x].onmouseup = frame.image[x].onmousemove = function(e) {
        e = e || event;
        if (e.type == "mousemove") { dragon.drag(e); } else dragon.drop(e);
        e.cancelBubble = true;
        clearTimeout(app.timeout);
        setTimeout(function() { app.maccontext = false; }, 10);
        return false;
      }
    } else {
      frame.image[x].oncontextmenu = (function(x) { return function(e) {
        e = e || event;
        e.returnValue = false;
        return contextMenu(e, x);
      }})(x);
    }
    frame.image[x].onclick = function(e) { return false; }
    frame.image[x].ondragstart = function(e) { return false; }
    frame.image[x].onselectstart = function(e) { return false; }
  }

  // ***** Reset dragon targets if the window is resized **************
  window.onresize = function() {
    for (var x = frame.image.length - 1, pos; x >= 0; x--) {
      pos = findPos(frame.image[x]);
      dragon.targets[x] = [pos[0], pos[1], pos[0] + frame.image[x].offsetWidth, pos[1] + frame.image[x].offsetHeight];
    }
  };


  // ***** Apply frame label event listeners **************************
  var labels = document.getElementById("labels").getElementsByTagName("td");
  for (var x = labels.length - 1; x >= 0; x--) {
    labels[x].id = "label" + (frame.slots - x - 1);
    labels[x].onclick = (function(y) { return function() { frame.highlight(y); }})(frame.slots - x - 1);
  }


  // ***** Apply status box event listeners ***************************
  var status = document.getElementById("status").tBodies[0].getElementsByTagName("tr");
  var stend = (page.slots % 2) ? status.length : status.length - 1;
  for (var x = 0; x < stend; x++) {
    if (status[x].cells[0].firstChild.nodeName == "#text") {
      status[x].cells[0].id = "status_no" + x;
      status[x].cells[1].id = "status_entry" + x;
      status[x].cells[0].onclick = status[x].cells[1].onclick = (function(x) { return function() { frame.highlight(x); }})(x);
      status[x].cells[0].ondblclick = status[x].cells[1].ondblclick = function(e) { app.selectorDisplay(true); }
    }

    if (status[x].cells[2]) {
      var adj = (status[x].cells[2].className == "divider") ? 1 : 0;
      if (status[x].cells[2 + adj].firstChild.nodeName == "#text") {
        status[x].cells[2 + adj].id = "status_no" + (x + stend);
        if (!(page.slots % 2) || x + status.length < 15) {
          status[x].cells[2 + adj].onclick = status[x].cells[3 + adj].onclick = (function(x) { return function() { frame.highlight(x); }})(x + stend);
          status[x].cells[2 + adj].ondblclick = status[x].cells[3 + adj].ondblclick = function(e) { app.selectorDisplay(true); }
        }
        status[x].cells[3 + adj].id = "status_entry" + (x + stend);
      }
    }
  }


  // ***** Hook dragon claws into the headers of popup "windows" ******
  makeStdwin(0);
  document.getElementById("selector").getElementsByTagName('img')[0].onclick = function() {
    this.parentNode.style.display = "none";
  };


  // ***** Capture keypresses *****************************************
  document.documentElement.onkeydown = function(e) {
    e = e || event;
    switch (e.keyCode) {
      case 13: app.selectorDisplay(true); break;
      case 37: frame.highlight(Math.min(frame.slots - 1, app.cursor + frame.slot[app.cursor].slots)); break;
      case 39: frame.highlight(Math.max(0, --app.cursor)); break;
      case 46: frame.place(app.cursor, 0, false); break;
      case 67: if (e.ctrlKey) frame.clip('copy'); break;
      case 86: if (e.ctrlKey) frame.clip('paste'); break;
      case 88: if (e.ctrlKey) { frame.clip('copy'); frame.place(app.cursor, 0, false); } break;
    }
  }
  var inputs = document.getElementsByTagName('input');
  for (var x = 0; x < inputs.length; x++)
    inputs[x].onkeydown = function(e) { e = e || event; e.cancelBubble = true; return true; }


  // ***** Handle keypress input in the selection dialog **************
  document.getElementsByName('module_filter')[0].onkeydown = function(e) {
    e = e || event;
    e.cancelBubble = true;

    var sellist = document.getElementById('selector').getElementsByTagName('ul')[0];
    var slottype = frame.image[app.cursor].ptype;

    switch (e.keyCode) {
      case 38: // ******************** Up
        if (app.fopts.length) {
          if (app.selkirk > -1) {
            app.fopts[app.selkirk].className = app.fopts[app.selkirk].className.removeWord("chosen");
            app.fopts[app.selkirk = Math.max(app.selkirk - 1, 0)].className += " chosen";
          } else app.fopts[app.selkirk = Math.min(app.fopts.length, Math.floor((sellist.scrollTop + sellist.offsetHeight) / 16)) - 1].className += " chosen";

          if ((app.selkirk + 1) * 16 > sellist.scrollTop + sellist.offsetHeight) {
            sellist.scrollTop = (app.selkirk + 1) * 16 - sellist.offsetHeight + 2;
          } else if (app.selkirk * 16 < sellist.scrollTop) sellist.scrollTop = app.selkirk * 16;

          var thismod = app.fopts[app.selkirk].firstChild.nodeValue;
          document.getElementById('preview').src = modules[modHash[thismod]].fileName(slottype);
        } else document.getElementById('preview').src = modules[0].fileName(slottype);
        return false;

      case 40: // ******************** Down
        if (app.fopts.length) {
          if (app.selkirk > -1) {
            app.fopts[app.selkirk].className = app.fopts[app.selkirk].className.removeWord("chosen");
            app.fopts[app.selkirk = Math.min(app.selkirk + 1, app.fopts.length - 1)].className += " chosen";
          } else app.fopts[app.selkirk = Math.max(0, Math.ceil(sellist.scrollTop / 16))].className += " chosen";

          if ((app.selkirk + 1) * 16 > sellist.scrollTop + sellist.offsetHeight) {
            sellist.scrollTop = (app.selkirk + 1) * 16 - sellist.offsetHeight + 2;
          } else if (app.selkirk * 16 < sellist.scrollTop) sellist.scrollTop = app.selkirk * 16;

          var thismod = app.fopts[app.selkirk].firstChild.nodeValue;
          document.getElementById('preview').src = modules[modHash[thismod]].fileName(slottype);
        } else document.getElementById('preview').src = modules[0].fileName(slottype);
        return false;

      case 32:
      case 13: // ******************** Enter & Spacebar
        if (app.selkirk > -1) {
          app.fopts[app.selkirk].onclick();
          document.getElementsByName("module_filter")[0].blur();
          app.selkirk = -1;
        } return false;

      case 27: // ******************** ESC
        app.selectorDisplay(false);
        break;

      default: // ********************
        // alert(e.keyCode);
    }
    return true;
  }
  document.getElementsByName('module_filter')[0].onkeypress = document.getElementsByName('module_filter')[0].onkeyup = function(e) {
    e = e || event;
    e.cancelBubble = true;
    switch (e.keyCode) {
      case 38: case 40: case 32: case 13: case 27:
        return false;
      default:
        clearTimeout(app.timeout);
        app.timeout = setTimeout(function() { app.selectorFilter(); }, 200);
    }
    return true;
  }

  if (document.getElementById('saleslink'))
    document.getElementById('saleslink').target = "_blank";


  // ***** Populate the picklist with all modules *********************
  var picklist = document.getElementById("selector").getElementsByTagName('ul')[0];
  var pickitem = picklist.getElementsByTagName('li');
  while (picklist.firstChild) picklist.removeChild(picklist.firstChild);
  for (var x = 0; x < modules.length; x++) {
    var li = document.createElement("li");
        li.uname = modules[x].name.toUpperCase();
        li.appendChild(document.createTextNode(modules[x].name));
      if (page.power) {
        var span = document.createElement("span");
            span.appendChild(document.createTextNode(" (" + modules[x].power + ")"));
          li.appendChild(span);
      }
        li.onmouseover = (function(x) { return function() {
          clearTimeout(app.seltime);
          document.getElementById('preview').src = modules[x].fileName(frame.image[app.cursor].ptype);
          this.className += " hover";
        }})(x);
        li.onmouseout = function() {
          if (app.selkirk > -1) {
            app.seltime = setTimeout(function() {
              document.getElementById('preview').src = modules[modHash[app.fopts[app.selkirk].firstChild.nodeValue]].fileName(frame.image[app.cursor].ptype);
            }, 50);
          }
          this.className = this.className.removeWord("hover");
        }
        li.onclick = (function(x) { return function() {
          frame.newmodule = true;
          if (frame.place(app.cursor, x, false))
            frame.highlight(app.cursor, true);
        }})(x);
    picklist.appendChild(li);
  }


  // Whew!  Initialization complete!


  // ***** Send to PHP loading function *******************************
  loadFrame();
  frame.refresh();

  document.body.className = "";
};





















/* ****************************************************************************************************************************************
 ******************************************************************************************************************************************
 ******************************************************************************************************************************************
 * Controlling application object
 *
 */
function Application() {
  var self = this;

  this.cursor = 6;

  this.view = "edit";
  this.locked = false;
  this.timeout = 0;
  this.maccontext = false;
  this.md5 = "";

  this.fopts = [];
  this.selkirk = 0;
  this.seltime = 0;

  this.online = false;
  this.mirror = false;

  this.check = 0;


  /* ******************************************************************
   * Switch Control Panels
   *
   */
  this.switchControl = function(tab) {
    if (this.mirror) {
      alert("This function is only available in the online version @ http:\x2f\x2fwww.evertz.com\x2fframe\x2f" + page.frame);
      return false;
    }

    if (this.locked) return false;
    this.hideDialogs();

    if (this.view != tab) {
      if (tab != "edit") {
        if (this.view == "edit") {
          this.quoteMessage("Working...", "", "");
          document.getElementById('link_send').disabled = "disabled";
          document.getElementById('link_send').onclick = "";
          if (!this.sendOutput()) return false;
        }
      } else document.getElementById('frameimage').style.visibility = "hidden";

      this.view = tab;

      if (document.getElementById('tabs_quote')) {
        document.getElementById('tabs_quote').className = (tab == "quote") ? "selected" : "";
        document.getElementById('page_quote').style.display = (tab == "quote") ? "block" : "none";
      }
      if (document.getElementById('tabs_export')) {
        document.getElementById('tabs_export').className = (tab == "export") ? "selected" : "";
        document.getElementById('page_export').style.display = (tab == "export") ? "block" : "none";
      }
      if (document.getElementById('tabs_save')) {
        document.getElementById('tabs_save').className = (tab == "save") ? "selected" : "";
        document.getElementById('page_save').style.display = (tab == "save") ? "block" : "none";
      }
      document.getElementById('page_edit').style.display = (tab == "edit") ? "block" : "none";

      if (document.getElementById('printsubtitle'))
        document.getElementById('printsubtitle').getElementsByTagName('span')[0].firstChild.nodeValue = document.getElementsByName('info_project')[0].value;

      var infos = ["author", "company", "country", "project", "frameid", "contact", "ponumber"];
      for (var x = 0; x < infos.length; x++)
        if (document.getElementById('print_' + infos[x]) && document.getElementsByName('info_' + infos[x])[0])
          document.getElementById('print_' + infos[x]).firstChild.nodeValue = document.getElementsByName('info_' + infos[x])[0].value + "\xa0";

      if (document.getElementById('print_power'))
        document.getElementById('print_power').firstChild.nodeValue = document.getElementById('display').firstChild.nodeValue + " / 600";

      if (document.getElementsByName('info_agent')[0])
        document.getElementById('print_agent').firstChild.nodeValue = document.getElementsByName('info_agent')[0].options[document.getElementsByName('info_agent')[0].selectedIndex].text;

      var today = new Date();
      var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
      document.getElementById('print_date').firstChild.nodeValue = months[today.getMonth()] + " " + today.getDate() + ", " + today.getFullYear();
    }
  };


  /* ********************************************************************
   * Convenience method to close all open dialogue windows
   *
   */
  this.hideDialogs = function() {
    document.getElementById('selector').style.display = 'none';
    document.getElementById("options").style.display = 'none';
    if (!this.maccontext) document.getElementById('slotContext').style.visibility = "hidden";
    document.getElementById('savednotice').style.display = "none";
    if (this.slidout) this.instrSlide(false, 10);
  };


	/* ********************************************************************
	 * Raise or lower the module selection dialogue box
	 *
	 */
	this.selectorDisplay = function(display) {
    if (this.locked) return false;

    var selector = document.getElementById('selector');
    var preview = document.getElementById('preview');
    var modfilt = document.getElementsByName("module_filter")[0];

    if (display) {
      this.hideDialogs();
	    if (this.slidout) this.instrSlide(false, 10);

      selector.style.display = 'block';
      modfilt.value = "";
      this.selectorFilter();

      var nam = frame.slot[this.cursor].name;
      if (nam != "Empty Slot") {
        for (var x = 0; x < this.fopts.length; x++)
          if (this.fopts[x].firstChild.nodeValue == nam)
            { this.selkirk = x; break; }
        
        var sellist = selector.getElementsByTagName('ul')[0];
        this.fopts[this.selkirk].className += " chosen";

        var thismod = this.fopts[this.selkirk].firstChild.nodeValue;
        preview.src = modules[modHash[thismod]].fileName(frame.image[app.cursor].ptype);
      }
      if (sellist) sellist.scrollTop = Math.max(0, this.selkirk * 16 - sellist.offsetHeight / 2 + 8);
      modfilt.focus();

    } else {
      selector.style.display = 'none';
      modfilt.blur();
    }
	};


	/* ********************************************************************
	 * Switch between frames of the same family
	 *
	 */
  this.switchPage = function(newPage) {
    if (encHash[newPage] !== undefined) {
      this.hideDialogs();

      for (var x = 0, conflict = false; x < frame.slots; x++)
        if (!modules[modHash[frame.slot[x].name]].allowed(enclosures[encHash[newPage]].type, enclosures[encHash[newPage]].frame, x)) conflict = true;

      if (!conflict || confirm('Some or all of your currently selected modules cannot be placed in the ' + newPage + ' frame.  Do you want to remove these modules and proceed anyway?')) {
        page = enclosures[encHash[newPage]];
        if (conflict)
          for (var x = 0; x < frame.slots; x++)
            if (!modules[modHash[frame.slot[x].name]].allowed(frame.image[x].ptype, page.frame, x)) frame.place(x, 0, true);

        document.getElementById('status').getElementsByTagName('strong')[0].firstChild.nodeValue = newPage + " ";

        var savedlink = document.getElementById('savednotice').getElementsByTagName('a')[0];
            savedlink.href = newPage + "?frame=" + self.md5;
            savedlink.getElementsByTagName('span')[0].firstChild.nodeValue = newPage + "?frame=" + self.md5;

        frame.refresh();
      }
    } else alert("Not a valid frame model!");
    document.getElementsByName('option_frame')[0].value = page.frame;
  };


	/* ********************************************************************
	 * Filter and display the list of available modules
	 *
	 */
	this.selectorFilter = function() {
    var filter = document.getElementsByName("module_filter")[0];
        filter.value = filter.value.toUpperCase();

    var picklist = document.getElementById("selector").getElementsByTagName('ul')[0];
    var pickitem = picklist.getElementsByTagName('li');
    var slottype = frame.image[app.cursor].ptype;

    this.fopts = [];
    for (var x = 0; x < pickitem.length; x++) {
      pickitem[x].className = "";
      if ((!filter.value || pickitem[x].uname.indexOf(filter.value) != -1) && modules[modHash[pickitem[x].firstChild.nodeValue]].allowed(slottype, page.frame, this.cursor)) {
        pickitem[x].style.display = "block";
        this.fopts.push(pickitem[x]);
      } else pickitem[x].style.display = "none";
    }

    document.getElementById('preview').src = modules[0].fileName(slottype);
    this.selkirk = -1;
    filter.focus();
	};


	/* ********************************************************************
	 * Raise or lower the module options selection dialogue box
	 *
	 */
	this.optionsDisplay = function(display) {
	  if (display) {
      this.hideDialogs();
	    if (this.slidout) this.instrSlide(false, 10);

      var options = document.getElementById("options");
        var optionsUL = options.getElementsByTagName("ul")[0];
          while (optionsUL.firstChild) optionsUL.removeChild(optionsUL.firstChild);

        var ti = 21;
  	    if (frame.slot[this.cursor].name.indexOf("xxx") > 0) {
	        var li = document.createElement('li');
              li.className = "wdm";
	          var h3 = document.createElement('h3');
	              h3.appendChild(document.createTextNode("DWDM Wavelength"));
	            li.appendChild(h3);
	          var select = document.createElement('select');
	              select.size = "1";
	              select.name = "dwdm";
                select.tabIndex = ti++;
	    	      for (var x = 200; x <= 600; x += 10) {
	              var option = document.createElement('option');
	                  option.value = x;
	                if (frame.slot[this.cursor].dwdm == x)
	                    option.setAttribute("selected", "selected");
	                  option.appendChild(document.createTextNode(x));
	                select.appendChild(option);
	            }
	            li.appendChild(select);
            optionsUL.appendChild(li);

  	    } else if (frame.slot[this.cursor].name.indexOf("xx") > 0) {
	        var li = document.createElement('li');
              li.className = "wdm";
	          var h3 = document.createElement('h3');
	              h3.appendChild(document.createTextNode("CWDM Wavelength"));
	            li.appendChild(h3);
	          var select = document.createElement('select');
	              select.size = "1";
	              select.name = "cwdm";
                select.tabIndex = ti++;
	    	      for (var x = 27; x <= 61; x += 2) {
	              if (x != 39 && x != 41) {
		              var option = document.createElement('option');
		                  option.value = x;
		                if (frame.slot[this.cursor].cwdm == x)
		                    option.setAttribute("selected", "selected");
		                  option.appendChild(document.createTextNode(x));
		                select.appendChild(option);
	              }
	            }
	            li.appendChild(select);
            optionsUL.appendChild(li);
	      }


        if (frame.slot[this.cursor].fibers) {
          var li = document.createElement('li');
            var h3 = document.createElement('h3');
                h3.appendChild(document.createTextNode("Fiber Connector"));
              li.appendChild(h3);
            var ul = document.createElement('ul');
              for (fbr in frame.slot[this.cursor].fiber) {
                if (typeof frame.slot[this.cursor].fiber[fbr] == "boolean") {
                  var li2 = document.createElement('li');
                    var label = document.createElement('label');
      								try{
      									var input = document.createElement('<input type="radio" name="fibers" value="' + fbr + '" tabindex="' + ti + '"' + ((frame.slot[this.cursor].fiber[fbr]) ? ' checked="checked"' : '') + ' />');
      								} catch(e) {
      									var input = document.createElement('input');
                            input.type = "radio";
                            input.name = "fibers";
                          if (frame.slot[this.cursor].fiber[fbr])
                              input.checked = "checked";
                            input.value = fbr;
                            input.tabIndex = ti;
      								}
                        label.appendChild(input);
                        label.appendChild(document.createTextNode(" " + fbr));
                      li2.appendChild(label);
                    ul.appendChild(li2);
                }
              }
              li.appendChild(ul);
            optionsUL.appendChild(li);
        }


        for (opt in frame.slot[this.cursor].option) {
          if (typeof frame.slot[this.cursor].option[opt] == "boolean") {
            var li = document.createElement('li');
              var description = optionDescriptions[opt] || "";

	            var label = document.createElement('label');
								try{
									var input = document.createElement('<input type="checkbox" value="' + opt + '" tabindex="' + ti + '"' + ((frame.slot[this.cursor].option[opt]) ? ' checked="checked"' : '') + ' />');
								} catch(e) {
									var input = document.createElement('input');
                      input.type = "checkbox";
                    if (frame.slot[this.cursor].option[opt])
                        input.checked = "checked";
                      input.value = opt;
                      input.tabIndex = ti;
								}
	                label.appendChild(input);
	                label.appendChild(document.createTextNode(" " + opt + " "));
	              if (description) {
	                var small = document.createElement('small');
	                    small.appendChild(document.createTextNode(description));
	                  label.appendChild(small);
	              }
              li.appendChild(label);
            optionsUL.appendChild(li);
          }
	      }

      options.getElementsByTagName('button')[0].tabIndex = ti;
	    options.style.display = 'block';
      options.style.left = ((innerDimensions()[0] - options.offsetWidth) / 2) + "px";
      options.getElementsByTagName('form')[0].elements[0].focus();

	  } else {
	    if (document.getElementById('options').style.display == 'block') {
	      document.getElementById('options').style.display = 'none';

	      var inputs = document.getElementById("options").getElementsByTagName('input');
	      for (var x = 0; x < inputs.length; x++) {
          if (inputs[x].name == "fibers") {
            if (typeof frame.slot[this.cursor].fiber[inputs[x].value] == "boolean")
    	        frame.slot[this.cursor].fiber[inputs[x].value] = (inputs[x].checked);
          } else {
            if (typeof frame.slot[this.cursor].option[inputs[x].value] == "boolean")
    	        frame.slot[this.cursor].option[inputs[x].value] = (inputs[x].checked);
          }
        }

	      var wavelength = document.getElementById("options").getElementsByTagName('select');
	      if (wavelength.length) {
	        wavelength = wavelength[0];
	        if (wavelength.name == "dwdm") frame.slot[this.cursor].dwdm = wavelength.value;
	        if (wavelength.name == "cwdm") frame.slot[this.cursor].cwdm = wavelength.value;
	      }

	      frame.refresh();
	    }
	  }
	};


  /* ******************************************************************
   * Wait for the image to finish loading before displaying
   *
   */
  this.frameImageWait = function() {
    var fraimg = document.getElementById('frameimage');
    if (fraimg.complete && (!fraimg.readyState || fraimg.readyState == "complete")) {
      document.getElementById('waiter').style.display = 'none';
      fraimg.style.visibility = 'visible';
      this.locked = false;
      document.body.className = "";
    } else setTimeout(function() { self.frameImageWait(); }, 200);
  };


  /* ******************************************************************
   * Change the Get Quote interface text
   *
   */
  this.quoteMessage = function(title, message, className) {
    var inter = document.getElementById('interface');
    while (inter.firstChild) inter.removeChild(inter.firstChild);

        inter.className = className;
      var h2 = document.createElement('h2');
          h2.appendChild(document.createTextNode(title));
        inter.appendChild(h2);
      var p = document.createElement('p');
          p.appendChild(document.createTextNode(message));
        inter.appendChild(p);
  };


	/* ********************************************************************
	 * Manual animation code
	 *
	 */
	this.slideRule = [350, 256, 128, 64, 32, 16, 8, 4, 2, 1, 0];
	this.sliding = false;
	this.slidout = false;
	this.instrSlide = function(direction, step) {
	  this.sliding = true;
	  document.getElementById('manual').style.top = -this.slideRule[step] + "px";

	  if (step == 0 || step == this.slideRule.length) {
	    if ((step == 0 && direction) || (step == this.slideRule.length && !direction)) {
        this.hideDialogs();
	    }

	    document.getElementById('manual').style.visibility = (direction) ? "visible" : "hidden";
	    document.getElementById('manualink').innerHTML = (direction) ? "Hide Instructions" : "View Instructions";
	  }

	  if (direction) { step++; } else step--;
	  if (step >= 0 && step < this.slideRule.length) {
	    setTimeout(function() { self.instrSlide(direction, step); }, 5);
	  } else {
	    this.sliding = false;
	    this.slidout = direction;
	  }
	};




  /* **************************************************************************************************************************************
   ************************** AJAX Stuff **************************************************************************************************
   ************************************************************************************************************************************* */


  /* ******************************************************************
   * Gather form information and send via AJAX
   *
   */
  this.sendOutput = function() {
    var values = [];

    this.locked = true;
    document.body.className = "wait";

    values.push("frame=" + page.frame);
    values.push("option_power=" + encodeURIComponent((document.getElementsByName('option_power')[0]) ? document.getElementsByName('option_power')[0].value : "no"));

    var infos = ["author", "company", "country", "project", "frameid", "contact", "agent", "ponumber"];
    for (var x = 0; x < infos.length; x++)
      if (document.getElementsByName('info_' + infos[x])[0])
        values.push("info_" + infos[x] + "="  + encodeURIComponent(document.getElementsByName('info_' + infos[x])[0].value));

    for (var x = 0; x < frame.slots; x++) {
      if (!frame.slot[x].multi && frame.slot[x].name != "Empty Slot") {
        values.push("module" + x + "=" + encodeURIComponent(frame.slot[x].fullName(2)));
        values.push("image" + x + "=" + encodeURIComponent(frame.slot[x].fileName(0)));
      }
    }

    var waiter = document.getElementById('waiter');
        waiter.style.display = "block";
        waiter.style.left = ((innerDimensions()[0] - waiter.offsetWidth) / 2) + "px";


    var http = getHTTPObject();
    http.open("POST", "store.php", true);
    http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    http.onreadystatechange = function() {
      if (http.readyState == 4) {
        self.md5 = http.responseXML.getElementsByTagName('md5');
        var err = http.responseXML.getElementsByTagName('error');

        if (self.md5.length) {
          var sent = http.responseXML.getElementsByTagName('sent')[0].firstChild.nodeValue;

          self.md5 = self.md5[0].firstChild.nodeValue;

          // Firefox hack to force reset of image.complete
          var img = document.createElement('img');
              img.src = "frame.php?frame=" + page.frame + "&method=png&id=" + self.md5;
              img.alt = "Completed " + page.name;
              img.className = "showcase";
              img.onclick = function() { self.switchControl('edit'); };

          var old = document.getElementById('frameimage').parentNode.replaceChild(img, document.getElementById('frameimage'));
              old = null;

              img.id = "frameimage";

          if (document.getElementById('tabs_quote')) {
  	        if (sent == "no") {
  	          for (var i = 0, empty = true; i < frame.slots; i++) if (frame.slot[i].name != "Empty Slot") empty = false;
  	          if (!empty) {
  	            if (document.getElementsByName('info_agent')[0].value != "" &&
  	                document.getElementsByName('info_agent')[0].value != "None selected" &&
  	                document.getElementsByName('info_contact')[0].value) {
  	              document.getElementById('link_send').disabled = "";
  	              document.getElementById('link_send').onclick = function() { self.getQuote(); };

  	              self.quoteMessage("Ready to Send", "Click the \"Send Frame\" button to send this frame to " + document.getElementsByName('info_agent')[0].options[document.getElementsByName('info_agent')[0].selectedIndex].text + ".", "");
  	            } else self.quoteMessage("Information Required", "To send your frame, please continue editing, being sure to select a Sales Agent and include your Contact Information.", "");
  	          } else self.quoteMessage("Frame is Empty", "Please select your desired modules before sending a frame layout.", "");
  	        } else self.quoteMessage("Already Sent", "This frame has already been mailed to the associated sales agent. If you wish to send multiple but similar frames, please use a different Project Name and/or Frame ID for each.", "");
          }

          document.getElementById('link_save_png').href = "frame.php?frame=" + page.frame + "&method=png&id=" + self.md5;
          document.getElementById('link_save_eps').href = "frame.php?frame=" + page.frame + "&method=eps&id=" + self.md5;
          document.getElementById('link_save_dxf').href = "frame.php?frame=" + page.frame + "&method=dxf&id=" + self.md5;

          setTimeout(function() { self.frameImageWait(); }, 200);
        } else if (err.length) self.quoteMessage("Frame ID Error", "There was an error finding the frame ID when trying to complete the frame.  Please try again.", "");
      }
    };
    http.send(values.join("&"));

    return true;
  };


  /* ******************************************************************
   * Send this frame ID via AJAX to get a quote
   *
   */
  this.getQuote = function() {
    document.getElementById('link_send').disabled = "disabled";

    var http = getHTTPObject();
    http.open("GET", "/includes/ajax/frame.send.php?type=" + page.type + "&id=" + this.md5, true);
    http.onreadystatechange = function() {
      if (http.readyState == 4) {
        switch (http.responseText) {
          case "Success": self.quoteMessage("Thank you!", "This " + page.name + " layout has been sent to your selected sales agent.", "complete"); break;
          case "Invalid": self.quoteMessage("Error!", "There was a problem in transferring the data to be mailed.  Please go back to the editing page and try again.", "error"); break;
          case "AlreadySent": self.quoteMessage("Have patience...", "This frame and the associated information has already been mailed to your selected sales agent.", "error"); break;
          case "NotFound": self.quoteMessage("I'm sorry!", "I could not find any completed frames in the database which match yours; it may have expired.  Please go back to the editing page and try again.", "error"); break;
          case "Fail": default: self.quoteMessage("Error!", "I'm sorry, but it seems the message could not be sent.  Please go back to the editing page and try again.", "error"); break;
        }
      }
    };
    http.send(null);
  };


  /* ******************************************************************
   * Bookmark this configuration
   *
   */
  this.getBookmark = function() {
    try { http.abort(); } catch(e) {}

    var http = getHTTPObject();
    http.open("GET", "/frame/saverecall.php?type=" + page.type + "&method=bookmark&id=" + this.md5, true);
    http.onreadystatechange = function() {
      if (http.readyState == 4) {
        if (http.responseText == "Saved") {
          var saved = document.getElementById('savednotice');
            var savedlink = saved.getElementsByTagName('a')[0];
                savedlink.href = page.frame + "?frame=" + self.md5;
                savedlink.getElementsByTagName('span')[0].firstChild.nodeValue = page.frame + "?frame=" + self.md5;
              saved.style.display = "block";
              saved.style.left = ((innerDimensions()[0] - saved.offsetWidth) / 2) + "px";
        } else alert(http.responseText);
      }
    };
    http.send(null);
    return false;
  };


  /* ******************************************************************
   * Find out whether the currently highlighted module has a block
   *  diagram
   *
   */
  this.findBlock = function(parentProd) {
    var rand = new Date();
    this.check.abort();
    this.check.open("HEAD", "/products/block/" + parentProd.replace(/\//g, ".") + ".pdf?" + rand.getTime(), true);
    this.check.onreadystatechange = function() {
      if (self.check.readyState == 4) {
        var scbd = document.getElementById('scBlockDiagram');
        scbd.className = (self.check.status == 200) ? "" : "disabled";
        scbd.getElementsByTagName('a')[0].href = "../products/block/" + parentProd.replace(/\//g, ".") + ".pdf";
      }
    };
    this.check.send(null);
  };
}

















/* ****************************************************************************************************************************************
 ******************************************************************************************************************************************
 ******************************************************************************************************************************************
 * Frame object
 *
 */
function Frame() {
  var self = this;

  this.slots       = page.slots;
  this.slot        = [];
  this.image       = [];
  this.clipboard   = cloneObject(modules[0]);
  this.newmodule   = false;
  // this.plateWidth  = page.width;
  // this.plateHeight = page.height;

  for (var i = 0; i < this.slots; i++)
    this.slot[i]   = cloneObject(modules[0]);


  /* ******************************************************************
   * Highlight a selected module
   *
   */
  this.highlight = function(slot) {
    if (app.locked) return false;
    if (app.view != "edit") app.switchControl('edit');

    while (this.slot[slot].multi) slot--;

    for (var i = 0; i < this.slots; i++) {
      if (i >= slot && i < slot + this.slot[slot].slots) {
        document.getElementById("label" + i).className = "selected";
        document.getElementById("status_no" + i).className = "selected";
      } else {
        document.getElementById("label" + i).className = "";
        document.getElementById("status_no" + i).className = "";
      }
    }

    if (slot != app.cursor) {
      app.hideDialogs();
      app.cursor = slot;
    }

    document.getElementById("module").firstChild.nodeValue = this.slot[app.cursor].name;
    document.getElementById('buttonFill').className = (this.slot[app.cursor].name == "Empty Slot") ? "button inactive" : "button";
    document.getElementById('buttonCopy').className = (this.slot[app.cursor].name == "Empty Slot") ? "button inactive" : "button";
    for (var i = 0, empty = true; i < this.slots; i++) if (this.slot[i].name != "Empty Slot") empty = false;
    document.getElementById('buttonClearAll').className = (empty) ? "button inactive" : "button";
    
    if (this.newmodule && this.slot[app.cursor].anyopt) app.optionsDisplay(true);

    this.newmodule = false;
    return app.cursor;
  };


  /* ******************************************************************
   * Copy or Paste items to/from the clipboard
   *
   */
  this.clip = function(action) {
    if (action == "copy" && this.slot[app.cursor].name != "Empty Slot") {
      document.getElementById('scPaste').className = "";

      this.clipboard = cloneObject(this.slot[app.cursor]);

      document.getElementById("clipboard").innerHTML = this.clipboard.fullName(0);
      document.getElementById('buttonPaste').className = "button";

    } else if (action == "paste" && this.clipboard.name != "Empty Slot") {
      if (this.place(app.cursor, modHash[this.clipboard.name], false)) {
        this.slot[app.cursor].subTransfer(this.clipboard);
        this.refresh();
      }
    }
  };


  /* ******************************************************************
   * Fill frame with currently selected module
   *
   */
  this.fill = function() {
    if (this.slot[app.cursor].name != "Empty Slot") {
      for (var i = 0; i < this.slots; i++) {
        if (i != app.cursor && this.slot[i].name == "Empty Slot") {
          if (this.place(i, modHash[this.slot[app.cursor].name], true)) {
            this.slot[i].subTransfer(this.slot[app.cursor]);
            if (i == 0 && page.fc.length && !page.fc.find(this.slot[app.cursor].name)) setTimeout(function() { self.fcswitch(); }, 10);
            i += this.slot[app.cursor].slots - 1;
          }
        }
      }
      this.refresh();
    }
  };


  /* ******************************************************************
   * Clear all modules from the frame
   *
   */
  this.clear = function() {
    for (var i = 0, empty = true; i < this.slots; i++) if (this.slot[i].name != "Empty Slot") empty = false;
    if (!empty && confirm('Really clear all modules?')) {
      for (var i = 0; i < this.slots; i++) this.slot[i] = cloneObject(modules[0]);
      this.refresh();
    }
  };


  /* ******************************************************************
   * Refresh the entire frame after a change has been made
   *
   */
  this.refresh = function() {
    for (var i = 0, power = 10; i < this.slots; i++) {
      this.slot[i].multi = false;

      var title = modules[modHash[this.slot[i].name]].descrip;
      var modu = document.getElementById("module" + i);
          modu.style.display = "block";
          modu.style.width = (this.slot[i].slots * page.panel[0]) + "px";
        if (page.frame == "3700FR") {
          if (i < 8) {
              modu.style.left = ((this.slots - i - this.slot[i].slots - 14) * 50) + "px";
          } else if (i < 16) {
              modu.style.left = ((this.slots - i - this.slot[i].slots - 6) * 50) + "px";
          } else modu.style.left = ((this.slots - i - this.slot[i].slots + 9) * 50) + "px";
        } else {
            modu.style.top = "0px";
            modu.style.left = (page.panel[0] - page.overlap) * (this.slots - i - this.slot[i].slots) + "px";
        }
          modu.src = this.slot[i].fileName(modu.ptype);
          modu.title = (title != "Empty Slot") ? title : "";
      document.getElementById("status_entry" + i).innerHTML = this.slot[i].fullName(0);
      power += modules[modHash[this.slot[i].name]].power;

      for (var j = i + 1; j < i + this.slot[i].slots; j++) {
        this.slot[j].multi = true;
        var modj = document.getElementById("module" + j);
            modj.style.display = "none";
            modj.src = modules[0].fileName(modj.ptype);
            modj.title = (title != "Empty Slot") ? title : "";
        document.getElementById("status_entry" + j).innerHTML = " &nbsp; &ndash;";
      }
      i = j - 1;
    }
    if (page.power) {
	    if (power <= 540) document.getElementById('value').style.backgroundColor = "#00c800";
	    if (power > 540 && power <= 600) document.getElementById('value').style.backgroundColor = "#ffd700";
	    if (power > 600) document.getElementById('value').style.backgroundColor = "#ff0000";
	    document.getElementById('value').style.width = Math.ceil(0.25 * power) + "px";
	    document.getElementById('display').firstChild.nodeValue = power;
    }
    this.highlight(app.cursor);
  };


  /* ******************************************************************
   * Place a module into the frame
   *
   */
  this.place = function(slot, modNum, silent) {
    app.hideDialogs();
    if (!modules[modNum].allowed(frame.image[slot].ptype, page.frame, slot) || this.slot[slot].multi) return false;

    for (var i = slot + 1, special3700fr; i < slot + modules[modNum].slots; i++) {
      special3700fr = (page.frame == "3700FR" && (i == 8 || i == 16)); // Special condition for 3700FR

      if (i >= this.slots || special3700fr || this.slot[i].name != "Empty Slot") {
        special3700fr = (page.frame == "3700FR" && (slot == 8 || slot == 16)); // Special condition for 3700FR

        if (slot == 0 || special3700fr || this.slot[slot - 1].multi || this.slot[slot - 1].name != "Empty Slot") {
          if (!silent) alert("There is not enough room to place this module here.\nThis module requires " + modules[modNum].slots + " available slots.");
          this.newmodule = false;
          return false;
        } else i = --slot + 1;
      }
    }

    // Remove existing module
    for (var i = slot, j = this.slot[slot].slots; i < slot + j; i++)
      this.slot[i] = cloneObject(modules[0]);

    if (modNum) {
      // Paste new module
      this.slot[slot] = cloneObject(modules[modNum]);
      for (var x = slot + 1; x < slot + this.slot[slot].slots; x++) this.slot[x].multi = true;

      if (!silent) {
        app.cursor = slot;
        this.refresh();
        if (slot == 0 && modules[modNum].name != "Empty Slot" && page.fc.length && !page.fc.find(modules[modNum].name))
          setTimeout(function() { self.fcswitch(); }, 10);
      }
    } else if (!silent) this.refresh();

    return true;
  };

  /* ******************************************************************
   * Toggle redundant power supply
   *
   */
  this.setrps = function() {
    if (app.locked) return false;
    if (app.view != "edit") app.switchControl('edit');
    app.hideDialogs();

    if (page.rpsu) {
      var rps = document.getElementsByName('option_power')[0];
      document.getElementById('psu2').src = (rps.value == "yes") ? "rear/" + page.type + "/" + page.psu + ".png" : "rear/" + page.type + "/" + page.psu + page.rpsu + ".png";
      document.getElementById('rpstoggle').src = (rps.value == "yes") ? "img/check-off.png" : "img/check-on.png";
      rps.value = (rps.value == "yes") ? "no" : "yes";
    }
  };


  /* ******************************************************************
   * Prompt user to replace their current slot 1 selection with a
   *  frame controller, if applicable
   *
   */
  this.fcswitch = function() {
    if (confirm("To monitor and/or control this frame using VistaLINK PRO or a 9000NCP Control Panel, slot one must contain a Frame Controller module.\n\nReplace the current module in slot one with a " + page.fc[0] + "?"))
      this.place(0, modHash[page.fc[0]], false);
  };
}














/* ****************************************************************************************************************************************
 ******************************************************************************************************************************************
 ******************************************************************************************************************************************
 * Cross-browser drag'n and drop'n object
 *
 */
function Dragon() {
  this.obj = null;
  this.active = false;
  this.slots = 0;
  this.cursor = 0;
  this.target = 0;
  this.targets = [];
  this.offsetX = 0;
  this.offsetY = 0;
  this.dummy = {};

  
  /* ******************************************************************
   * Hook the object to be dragged
   *
   */
  this.claw = function(e, x) {
    if (app.locked) return false;

    e = e || event;
    if (this.obj) this.drop(e);
    this.obj = e.target || e.srcElement;

    this.cursor = frame.highlight(x);

    if (frame.slot[this.cursor].name != "Empty Slot") {
      this.origpos = [this.obj.style.left, this.obj.style.top];
      this.obj.className = "dragon";
      this.offsetX = e.clientX - this.obj.parentNode.parentNode.offsetLeft - this.obj.offsetLeft;
      this.offsetY = e.clientY - this.obj.parentNode.parentNode.offsetTop - this.obj.offsetTop;
      this.slots = frame.slot[app.cursor].slots;
    } else this.obj = null;
  };


  /* ******************************************************************
   * Move the clawed object with the mouse
   *
   */
  this.drag = function(e) {
    e = e || event;
    if (this.obj) {
      this.active = true;
      document.getElementById('slotContext').style.visibility = "hidden";
      this.obj.style.left = Math.min(page.drag[0] + 20 - this.obj.offsetWidth , Math.max(-25, e.clientX - this.obj.parentNode.parentNode.offsetLeft - this.offsetX)) + "px";
      this.obj.style.top  = Math.min(page.drag[1] + 20 - this.obj.offsetHeight, Math.max( -5, e.clientY - this.obj.parentNode.parentNode.offsetTop  - this.offsetY)) + "px";
      e.cancelBubble = true;
    }
  };


  /* ******************************************************************
   * Drop an object and move a panel, if allowed
   *
   */
  this.drop = function(e) {
    e = e || event;
    if (this.obj) {
      var targetPos = findPos(this.obj);
      this.obj.style.left = this.origpos[0];
      this.obj.style.top = this.origpos[1];
      this.target = -1;

      if (this.active) {

        // Find the dropzone and compare notes
        for (var x = 0, d, dists = []; x < this.targets.length; x++)
          if ((d = Math.sqrt(Math.pow(targetPos[0] - this.targets[x][0], 2) + Math.pow(targetPos[1] - this.targets[x][1], 2))) < 40)
            dists.push([x, d]);
        if (dists.length) {
          dists.sort(function(a, b) { return a[1] - b[1]; });
          this.target = dists[0][0] - frame.slot[this.cursor].slots + 1;
        }

        if (this.target != -1 && this.target != this.cursor && modules[modHash[frame.slot[this.cursor].name]].allowed(frame.image[this.target].ptype, page.frame, this.target)) {
          this.dummy = cloneObject(frame.slot[this.cursor]);
          frame.place(this.cursor, 0, true);

          for (var x = this.target, allowed = true; x < this.target + frame.slot[this.target].slots; x++)
            if (frame.slot[x].name != "Empty Slot" || frame.slot[x].multi) allowed = false;

          app.cursor = this.target;
          if (allowed && frame.place(this.target, modHash[this.dummy.name], true)) {
            frame.slot[this.target].subTransfer(this.dummy);
            if (this.target == 0 && frame.slot[this.target].name != "Empty Slot" && page.fc.length && !page.fc.find(frame.slot[this.target].name))
              setTimeout(function() { frame.fcswitch(); }, 10);
          } else {
            app.cursor = this.cursor;
            frame.place(this.cursor, modHash[this.dummy.name], true);
            frame.slot[this.cursor].subTransfer(this.dummy);
          }
          this.dummy = null;
        }
        frame.refresh();
      }

      this.obj.className = "";
      this.obj = null;
      this.active = false;
    }    
  };
}






/* ********************************************************************
 * Handle the appearance and content of the context menu
 *
 */
function contextMenu(e, x) {
  if (app.locked) return false;
  if (app.maccontext) return false;

  e.returnValue = false;

  app.hideDialogs();
  frame.highlight(x);

  for (var i = 0, empty = true, blank = true; i < frame.slots;) {
    if (frame.slot[i].name != "Empty Slot") {
      empty = false;
      if (i == x) blank = false;
    } i += frame.slot[i].slots;
  }

  document.getElementById('scDelete').className = document.getElementById('scCut').className = document.getElementById('scCopy').className = document.getElementById('scFill').className = (blank) ? "disabled" : "";
  var scOptions = document.getElementById('scOptions');
  if (scOptions) scOptions.className = (frame.slot[x].anyopt) ? "" : "disabled";
  document.getElementById('scClearFrame').className = (empty) ? "disabled" : "";

  var scWebpage = document.getElementById('scWebpage');
  if (scWebpage) {
    if (!blank && modules[modHash[frame.slot[x].name]].parent) {
      document.getElementById('scWebpage').className = "";
      document.getElementById('scWebpage').getElementsByTagName('a')[0].href = "../products/" + modules[modHash[frame.slot[x].name]].parent + ((app.mirror) ? ".html" : "");

      if (!app.mirror)
        setTimeout((function(parentProd) { return function() { app.findBlock(parentProd); }})(modules[modHash[frame.slot[x].name]].parent), 0);
    } else {
      document.getElementById('scWebpage').className = "disabled";
      if (!app.mirror) document.getElementById('scBlockDiagram').className = "disabled";
    }
  }

  var cont = document.getElementById('slotContext');
      var top = e.clientY + scrollDist()[1];
      if (top + cont.offsetHeight > innerDimensions()[1]) top -= cont.offsetHeight;
      cont.style.top = top + "px";
      cont.style.left = e.clientX + "px";
      cont.style.visibility = "visible";

  return false;
}