﻿var _timerId = 0;
var _stocks = new Hashtable ();
var _selectedIndex = -1;
var _showAll = false;
var _progressBar = null;

function focusTextbox (textboxId)
{
  var textbox = document.getElementById (textboxId);
  if (textbox != null)
    textbox.focus ();
}

function keyDown (e, textboxId, contentId, isIE)
{
  cancelPendingLookup ();
  var keyCode = getKeyCode (e);
  
  // handle enter (13), escape (27), up arrow (38), down arrow (40)
  if ((keyCode == 13) || (keyCode == 27) || (keyCode == 38) || (keyCode == 40))
      updateLookup (keyCode, textboxId, contentId, isIE);
}

function keyUp (e, textboxId, contentId, isIE)
{
  // handle 0-9, A-Z, backspace (8), space (32), dot (190)
  var keyCode = getKeyCode (e);
 
  if (((keyCode >= 48) && (keyCode <= 90)) || (keyCode == 8) || (keyCode == 32) || (keyCode == 190))
  {
    cancelPendingLookup ();
    document.body.style.cursor = 'wait';
    _timerId = setTimeout ('updateLookup (' + keyCode + ',\'' + textboxId + '\',\'' + contentId + '\',' + isIE + ')', 250);
  }
}

function getKeyCode (e)
{
  var keyCode = 0;
  if (e)
	  keyCode = window.event ? e.keyCode : e.which;
	return keyCode;
}

function cancelPendingLookup ()
{
  if (_timerId > 0)
  {
    clearTimeout (_timerId);
    document.body.style.cursor = 'default';
  }
}

function updateLookup (keyCode, textboxId, contentId, isIE)
{
  var textbox = document.getElementById (textboxId);
  var content = document.getElementById (contentId);

  if (keyCode == 13) // enter
  {
    if (content.style.visibility == 'visible')
    {
      if ((_selectedIndex > -1) && (_selectedIndex < content.childNodes.length))
        textbox.value = content.childNodes [_selectedIndex].getAttribute ('symbol');
        hideLookup (textboxId, contentId, isIE);
    }
  }
  else if (keyCode == 27) // escape
  {
    if (content.style.visibility == 'visible')
      hideLookup (textboxId, contentId, isIE);
    textbox.value = '';
  }
  else if (keyCode == 38) // up arrow
  {
    if (content.style.visibility == 'visible')
      selectNode (-1, contentId);
  }
  else if (keyCode == 40) // down arrow
  {
    if ((content.style.visibility != 'visible') && (textbox.value.length > 0))
    {
      getMatchingSymbols (textboxId, contentId, isIE);
      showLookup (textboxId, contentId, isIE);
    }
    selectNode (1, contentId);
  }
  else if (((keyCode >= 48) && (keyCode <= 90)) || (keyCode == 8) || (keyCode == 32) || (keyCode == 190)) // 0-9, A-Z, backspace (8), space (32), dot (190)
  {
    if (textbox.value.length == 0)
      hideLookup (textboxId, contentId, isIE);
    else
      getMatchingSymbols (textboxId, contentId, isIE);

    if (content.hasChildNodes () == true)
      showLookup (textboxId, contentId, isIE);
    else
      hideLookup (textboxId, contentId, isIE);

    content.scrollTop = 0;
    _selectedIndex = -1;
  }

  document.body.style.cursor = 'default';
}

function hideLookup (textboxId, contentId, isIE)
{
  var content = document.getElementById (contentId);
  while (content.hasChildNodes ())
	  content.removeChild (content.firstChild);

  content.style.visibility = 'hidden';
  if (isIE == false)
    content.style.display = 'none';

  _showAll = false;
  focusTextbox (textboxId);
}

function showLookup (textboxId, contentId, isIE)
{
  var content = document.getElementById (contentId);
  content.style.visibility = (content.hasChildNodes () ? 'visible' : 'hidden');
  if (isIE == false)
    content.style.display = (content.hasChildNodes () ? 'block' : 'none');
}

function selectNode (increment, contentId)
{
  var content = document.getElementById (contentId);
  if (content.hasChildNodes () == true)
  {
    var lastChild = (content.childNodes.length - 1);
    if ((_showAll == false) && (lastChild >= 10))
      --lastChild;

    if ((_selectedIndex > -1) && (_selectedIndex <= lastChild))
      content.childNodes [_selectedIndex].className = 'SymbolLookup';

    _selectedIndex += increment;
    if (_selectedIndex < 0)
      _selectedIndex = 0;
    else if (_selectedIndex > lastChild)
      _selectedIndex = lastChild;

    content.childNodes [_selectedIndex].className = 'SelectedSymbolLookup';
    if (lastChild > 10)
    {
      var itemTop = content.childNodes [_selectedIndex].offsetTop;
      var itemHeight = content.childNodes [_selectedIndex].offsetHeight;

      if (content.scrollTop < (itemTop + itemHeight - content.offsetHeight))
        content.scrollTop += (itemHeight + 1);
      else if (itemTop < content.scrollTop)
        content.scrollTop -= (itemHeight + 1);

      if (itemTop < content.scrollTop)
        content.scrollTop = itemTop;
      else if (itemTop > (content.scrollTop + content.offsetHeight))
        content.scrollTop = itemTop;
    }
  }
}

function getMatchingSymbols (textboxId, contentId, isIE)
{
  var textbox = document.getElementById (textboxId);
  var content = document.getElementById (contentId);

  content.style.width = 'auto';
  while (content.hasChildNodes())
   content.removeChild (content.firstChild);
  
  if (textbox.value.length > 0)
  {
    var text = textbox.value.toUpperCase ();
    var name = _stocks.getItem (text);
    var sb = null;

    if (name != null)
    {
      sb = new StringBuilder ();
      sb.Append (name);
      sb.Append (' [<b>');
      sb.Append (text);
      sb.Append ('</b>]');
      addStockToList (content, text, sb.ConvertToString(), textboxId, contentId, isIE);
    }

    for (var symbol in _stocks.hashtable)
    {
      name = _stocks.getItem (symbol);
      sb = null;

      if (symbol.toUpperCase () == text) // already got this one
      {
      }      
      else if (symbol.toUpperCase ().indexOf (text) == 0) // first check for matching stock symbols
      {
        sb = new StringBuilder ();
        sb.Append (name);
        sb.Append (' [<b>');
        sb.Append (symbol.substr (0, text.length));
        sb.Append ('</b>');
        sb.Append (symbol.substring (text.length));
        sb.Append (']');
      }
      else if ((text.length == 1) && (name.charAt (0) == text) && (symbol.charAt (0) == text)) // if we've only got one character, make sure the symbol and the name match
      {
        sb = new StringBuilder ();
        sb.Append (name);
        sb.Append (' [<b>');
        sb.Append (symbol.substr (0, text.length));
        sb.Append ('</b>');
        sb.Append (symbol.substring (text.length));
        sb.Append (']');
      }
      else if ((text.length > 1) && (name.toUpperCase ().indexOf (text) == 0)) // then check for matching company names
      {
        sb = new StringBuilder ();
        sb.Append ('<b>');
        sb.Append (name.substr (0, text.length));
        sb.Append ('</b>');
        sb.Append (name.substring (text.length));
        sb.Append (' [');
        sb.Append (symbol);
        sb.Append (']');
      }
      
      if (sb != null)
      {
        if ((_showAll == false) && (content.childNodes.length == 10))
        {
          sb = new StringBuilder ();
          sb.Append ('<table><tr><td align="left" style="white-space: nowrap; padding-left: 10px; padding-right: 20px">');
          sb.Append ('<span style="font-size: x-small">First 10 matches shown</span></td>');
          sb.Append ('<td align="right" style="white-space: nowrap; padding-left: 20px; padding-right: 10px">');
          sb.Append ('<a href="javascript:viewAll(\'' + textboxId + '\',\'' + contentId + '\',' + isIE + ');" style="font-size: x-small"><span style="font-size: x-small">View All</span></a></td>');
          sb.Append ('</tr></table>');

          var div = document.createElement ('div');
          div.innerHTML = sb.ConvertToString ();
          content.appendChild (div);
        }
        else
        {
          addStockToList (content, symbol, sb.ConvertToString(), textboxId, contentId, isIE);
        }

        if ((_showAll == false) && (content.childNodes.length > 10))
          break;
      }
    }
  }

  adjustPosition (content, textbox);
}

function adjustPosition (content, textbox)
{
  // If the element is hidden we need to make it visible to calculate the positions.
  var vis = $(content).is(":visible");
  if (!vis)
    $(content).show();

  var contentWidth = Math.max($(content).width(), content.scrollWidth);
  var contentLeft = $(textbox).position().left;
  var documentWidth = document.body.clientWidth;

  // Adjust the left position if it doesn't fit in the container.
  if ((contentWidth + contentLeft + 8) > documentWidth)
    contentLeft = Math.max(5, (documentWidth - contentWidth - 8));
  $(content).css({ left: contentLeft });

  // If it still doesn't fit, put up the horizontal scroller.
  if ((contentWidth + contentLeft) > documentWidth)
  {
    contentWidth = (documentWidth - 13);
    $(content).css({ overflowX: 'scroll' });
  }
  
  // Set the width of the symbol list.
  $(content).width(contentWidth);

  // Adjust the height and vertical scroller.
  if ((_showAll == true) && (content.childNodes.length > 10))
  {
    content.style.height = '200px';
    content.style.overflowY = 'scroll';
  }
  else
  {
    content.style.height = 'auto';
    content.style.overflowY = 'hidden';
  }

  // Hide the element again if it wasn't visible when we started.
  if (!vis)
    $(content).hide();
}

function addStockToList (content, symbol, html, textboxId, contentId, isIE)
{
  var classAttribute = document.createAttribute ('class');
  classAttribute.nodeValue = 'SymbolLookup';

  var symbolAttribute = document.createAttribute ('symbol');
  symbolAttribute.nodeValue = symbol;

  var paragraph = document.createElement ('p');
  paragraph.setAttributeNode (classAttribute);
  paragraph.setAttributeNode (symbolAttribute);
  paragraph.innerHTML = html;
  paragraph.onclick = function() { symbolClicked (this, textboxId, contentId, isIE); }
  paragraph.onmouseover = function() { symbolMouseOver (this, textboxId, contentId, isIE); }
  paragraph.onmouseout = function() { symbolMouseOut (this, textboxId, contentId, isIE); }

  content.appendChild (paragraph);
}

function viewAll (textboxId, contentId, isIE)
{
  _showAll = true;
  getMatchingSymbols (textboxId, contentId, isIE);
  focusTextbox (textboxId);
}

function symbolClicked (symbol, textboxId, contentId, isIE)
{
  var textbox = document.getElementById (textboxId);
  textbox.value = symbol.getAttribute ('symbol');
  hideLookup (textboxId, contentId, isIE);
}

function symbolMouseOver (symbol, textboxId, contentId, isIE)
{
  symbol.className = 'SelectedSymbolLookup';
}

function symbolMouseOut (symbol, textboxId, contentId, isIE)
{
  symbol.className = (isSelectedSymbol (symbol, textboxId, contentId, isIE) ? 'SelectedSymbolLookup' : 'SymbolLookup');
}

function isSelectedSymbol (symbolNode, textboxId, contentId, isIE)
{
  var result = false;
  var content = document.getElementById (contentId);
  
  if ((content.hasChildNodes () == true)&& (_selectedIndex > -1) && (_selectedIndex < content.childNodes.length))
    result = (symbolNode == content.childNodes [_selectedIndex])
  
  return result;
}

function initTermsAndConditions (panelId, linkButtonId, offsetX, offsetY)
{
  var panel = document.getElementById (panelId);
  var linkButton = document.getElementById (linkButtonId);

  if ((linkButton != null) && (panel != null))
  {
    var pos = Sys.UI.DomElement.getLocation (linkButton);
    var panelWidth = parseInt (panel.style.width);
    var panelHeight = parseInt (panel.style.height);

    if (document.body.offsetWidth < (panelWidth + pos.x))
      panel.style.width = Math.min ((document.body.offsetWidth - pos.x - offsetX - 10), panelWidth) + 'px';

    if (document.body.offsetHeight < (panelHeight + pos.y))
      panel.style.height = Math.min ((document.body.offsetHeight - pos.y - offsetY - 25), panelHeight) + 'px';
  }
}

function Hashtable()
{
    this.clear = hashtable_clear;
    this.containsKey = hashtable_containsKey;
    this.containsValue = hashtable_containsValue;
    this.getItem = hashtable_get;
    this.isEmpty = hashtable_isEmpty;
    this.keys = hashtable_keys;
    this.putItem = hashtable_put;
    this.remove = hashtable_remove;
    this.size = hashtable_size;
    this.toString = hashtable_toString;
    this.values = hashtable_values;
    this.hashtable = new Array();
}

function hashtable_clear()
{
    this.hashtable = new Array();
}

function hashtable_containsKey(key)
{
    var exists = false;
    for (var i in this.hashtable)
    {
        if (i == key && this.hashtable[i] != null)
        {
            exists = true;
            break;
        }
    }
    return exists;
}

function hashtable_containsValue(value)
{
    var contains = false;
    if (value != null)
    {
        for (var i in this.hashtable)
        {
            if (this.hashtable[i] == value)
            {
                contains = true;
                break;
            }
        }
    }
    return contains;
}

function hashtable_get(key)
{
    return this.hashtable[key];
}

function hashtable_isEmpty()
{
    return (parseInt(this.size()) == 0) ? true : false;
}

function hashtable_keys()
{
    var keys = new Array();
    for (var i in this.hashtable)
    {
        if (this.hashtable[i] != null) 
            keys.push(i);
    }
    return keys;
}

function hashtable_put(key, value)
{
    if (key == null || value == null)
    {
        throw "NullPointerException {" + key + "},{" + value + "}";
    }
    else
    {
        this.hashtable[key] = value;
    }
}

function hashtable_remove(key)
{
    var rtn = this.hashtable[key];
    this.hashtable[key] = null;
    return rtn;
}

function hashtable_size()
{
    var size = 0;
    for (var i in this.hashtable)
    {
        if (this.hashtable[i] != null) 
            size ++;
    }
    return size;
}

function hashtable_toString()
{
    var result = "";
    for (var i in this.hashtable)
    {      
        if (this.hashtable[i] != null) 
            result += "{" + i + "},{" + this.hashtable[i] + "}\n";   
    }
    return result;
}

function hashtable_values()
{
    var values = new Array();
    for (var i in this.hashtable)
    {
        if (this.hashtable[i] != null) 
            values.push (this.hashtable[i]);
    }
    return values;
}

function StringBuilder ()
{
  this.buffer = [];
}

StringBuilder.prototype.Append = function (str)
{
  this.buffer [this.buffer.length] = str;
};

StringBuilder.prototype.ConvertToString = function ()
{
  return this.buffer.join ('');
};

var ProgressBar = function(divId, cellCount, tableCss, cellCss, width, height)
{
  var index = -1;
  var timerObj = new Timer();

  this.Init = function()
  {
    $("#" + divId).empty();

    var str = "<table class='" + tableCss + "' cellpadding='0' cellspacing='1'><tr>";
    for (var cnt = 0; cnt < cellCount; cnt++)
    {
      str += "<td style='width:" + width + "px; height:" + height + "px'><div class='" + cellCss + " " + cellCss + cnt + "' style='height:" + height + "px'></div></td>";
    }
    str += "</tr></table>";
    $("#" + divId).append(str);

    timerObj.Interval = 100;
    timerObj.Tick = timer_tick;
  }

  this.Start = function()
  {
    this.Init();
    timerObj.Start();
  }

  this.Stop = function()
  {
    timerObj.Stop();
  }

  function timer_tick()
  {
    index = index + 1;
    index = index % cellCount;

    $("#" + divId + " ." + cellCss + index).fadeIn(10);
    $("#" + divId + " ." + cellCss + index).fadeOut(500);
  }
}

// Declaring class "Timer"
var Timer = function()
{
  // Property: Frequency of elapse event of the timer in millisecond
  this.Interval = 1000;

  // Property: Whether the timer is enable or not
  this.Enable = new Boolean(false);

  // Event: Timer tick
  this.Tick;

  // Member variable: Hold interval id of the timer
  var timerId = 0;

  // Member variable: Hold instance of this class
  var thisObject;

  // Function: Start the timer
  this.Start = function()
  {
    this.Enable = new Boolean(true);

    thisObject = this;
    if (thisObject.Enable)
    {
      thisObject.timerId = setInterval(
                function()
                {
                  thisObject.Tick();
                }, thisObject.Interval);
    }
  };

  // Function: Stops the timer
  this.Stop = function()
  {
    thisObject.Enable = new Boolean(false);
    clearInterval(thisObject.timerId);
  };

};

