/* Temporary manual console for non-Firefox browsers */
var enable_debugger = false;
if (!console || !console.debug) {var console = {container:false,init:function(){if(console.container) return; console.container=$(document.createElement('div')); console.container.addClassName('console'); $$('body')[0].appendChild(console.container);}, debug:function(){if(!enable_debugger) return; console.init(); $A(arguments).each(function(arg){var div=$(document.createElement('div')); div.innerHTML=arg; console.container.appendChild(div)});}};}

// Cookie object
var Cookie = {
    set: function(name, value, daysToExpire) {var expire = ''; if (daysToExpire != undefined) {var d = new Date();d.setTime(d.getTime() + (86400000 * parseFloat(daysToExpire)));expire = '; expires=' + d.toGMTString();} var path = '; path=/'; if (value.length) value=escape(value); else value='""'; return (document.cookie = escape(name) + '=' + value + expire + path);},
    get: function(name) {var cookie = document.cookie.match(new RegExp('(^|;)\\s*' + escape(name) + '=([^;\\s]*)')); return (cookie ? unescape(cookie[2]) : '');},
    erase: function(name) {var cookie = Cookie.get(name) || true; Cookie.set(name, '', -1); return cookie;},
    accept: function() {if (typeof(navigator.cookieEnabled)=='boolean') {return navigator.cookieEnabled;} Cookie.set('_test', '1'); return (Cookie.erase('_test')=='1');}
};

function expandTA(ta) {
    if (ta.scrollHeight) {
        if ($(ta).rel!='fixedWidth') $(ta).setStyle({width:ta.getWidth()+'px'});
        $(ta).rel='fixedWidth';
        
        numlines = ta.value.split('\n').length
        //console.log('s lines',numlines)
        if(numlines > 3 && numlines < 30) {
        ta.setStyle({height: (numlines+1) * 15 +'px'})
        } 

        //$(ta).setStyle({height:(ta.scrollHeight>350 ? 350 : (ta.scrollHeight<80 ? 80 : ta.scrollHeight))+'px'});
    }
}

function serializeObject(o) {var a = new Array(); for(i in o) a[a.length]=encodeURI(i)+'='+encodeURI(o[i]); return(a.join('&'));}
function doAction(action, params, opts) {if (typeof(opts)=='undefined' || opts.length==0) var opts = new Object();if (typeof(params)=='undefined' || params.length==0) {var params = 'action='+encodeURI(action);} else {params += '&action='+encodeURI(action);}var options = new Object();options.method = 'post';options.postBody = params;options.evalScripts=true;if (opts.onComplete) {options.onComplete=opts.onComplete;} else if (opts.indicator) {options.onComplete = function(){$(opts.indicator).hide();}}if (opts.onFailure) options.onComplete=opts.onFailure;if (opts.onSuccess) options.onComplete=opts.onSuccess;if (typeof(opts.asynchronous)!=undefined) options.asynchronous=opts.asynchronous;var url = '/actions';if (opts.container) {new Ajax.Updater(opts.container, url, options);} else {new Ajax.Request(url, options);}}
function setFirstAndLast(o, childNodeName) {if (!$(o)) return; var nodes = $A($(o).getElementsByTagName(childNodeName)); nodes.each(function(node) {nodes.each(function(refNode) {if($(node).descendantOf(refNode)) {nodes = nodes.without(node);return;}});}); if(!nodes.length) return; $(nodes[0]).addClassName('first'); $(nodes[nodes.length-1]).addClassName('last');}
function setOddsAndEvens(o, childNodeName) {var odd=true; $A($(o).getElementsByTagName(childNodeName)).each(function(item) {$(item).addClassName((odd ? 'odd' : 'even')); odd=!odd;});}
function doJSON(endpoint, query, callback) {new Ajax.Request(endpoint, {parameters:query, onComplete:function(response){callback(eval('('+response.responseText+')'))}});}
function indicate(c, text) {c=$(c); if(!c) return; $(c).childElements().each(Element.remove); var x=document.createElement('div'); x.className="jumptop center"; var d=document.createElement('div'); d.className='indicator'; d.style.display='inline'; d.innerHTML=text; x.appendChild(d); c.appendChild(x);}
function yellowFade(c) {new Effect.Highlight(c, {startcolor: '#FFFFCC', restorecolor:true, duration:3});}
function clearChildren(element) {if(!element) return; while (element.firstChild) {element.removeChild(element.firstChild);}}

function getAbsoluteX_obj(obj) {$(obj).cumulativeOffset()[0];}
function getAbsoluteY_obj(obj) {$(obj).cumulativeOffset()[1];}
function inputHL(el, on) {if(on) Element.addClassName(el, 'cntoract-place-order-textbox-highlight'); else Element.removeClassName(el, 'contract-place-order-textbox-highlight');}

function mmorder(assetid, action, quantity){}

// Make div fields editable
prmEditableHelper = {has_replaced:false, has_clicked:false, replacedHTML:'', ta:null};
function makeEditable(o) {
    if (typeof(o.defaultText)=='undefined' || o.defaultText.length==0) o.defaultText='';
    if (typeof(o.parameterName)=='undefined' || o.parameterName.length==0) o.parameterName='text';
    if (typeof(o.extraParams)=='undefined' || o.extraParams.length==0) o.extraParams=new Object();
    if (typeof(o.message)=='undefined' || o.message.length==0) o.message = 'Click here to edit';
    if (typeof(o.widget)=='undefined' || o.widget.length==0) o.widget = 'textarea';
    if (typeof(o.persistent)=='undefined') o.persistent=false;

    var c = $(o.containerName);
    var h = prmEditableHelper;
    var f = null;
    if (c.empty()) {
        if (o.persistent) {c.addClassName('editablePersistent'); c.innerHTML = o.message;} else {if (c.getHeight()<10) {c.setStyle({height:'20px'});}}
    } else {
        if (!c.getElementsByClassName('editableEditLabel').length) {var editLabel = $(document.createElement('span')); editLabel.addClassName('editableEditLabel'); editLabel.appendChild(document.createTextNode(LC.EDIT)); c.appendChild(editLabel, c.firstChild);}
    }
    var click = function(e){
        if (h.has_clicked) return; h.has_clicked = true;
        if (!h.has_replaced) {h.replacedHTML = c.innerHTML;} h.has_replaced = true; c.innerHTML=''; c.setStyle({height:''});
        f = document.createElement('form'); $(f).addClassName('editableForm');
        f.setAttribute('onsubmit', 'return(false);');
        Event.observe(f, 'submit', function(e){
                o.defaultText = (h.ta ? h.ta.value : f[o.parameterName].value);
                doAction(o.action, Form.serialize(f)+'&'+serializeObject(o.extraParams), {onSuccess:function(r){
                            c.innerHTML=r.responseText;
                            h.has_clicked=false; h.has_replaced=false; c.removeClassName('editable'); c.removeClassName('editableText'); c.removeClassName('editablePersistent');
                            Event.stopObserving(c, 'click', click); Event.stopObserving(c, 'mouseover', mouseover); Event.stopObserving(c, 'mouseout', mouseout);
                            makeEditable(o); yellowFade(c);
                        }});
                Event.stop(e);
                return(false);
            });
        Event.observe(f, 'reset', function(e){
                c.innerHTML=h.replacedHTML;
                h.has_clicked=false; h.has_replaced=false; c.removeClassName('editable'); c.removeClassName('editableText');
                Event.stopObserving(c, 'click', click); Event.stopObserving(c, 'mouseover', mouseover); Event.stopObserving(c, 'mouseout', mouseout);
                makeEditable(o);
                return(false);
            });
        var d = document.createElement('div');
        if (o.widget=='text') {
            var ta = document.createElement('input'); ta.setAttribute('type', 'text'); ta.setAttribute('name', o.parameterName); ta.className = 'input'; ta.value=o.defaultText;
            if (typeof(o.maxlength)!='undefined') ta.setAttribute('maxlength', o.maxlength);
        } else if (o.widget=='select') {
            var ta = document.createElement('select'); ta.setAttribute('name', o.parameterName); ta.className = 'small discrete';
            for (i in o.selectOptions) {var option = document.createElement('option'); option.value=i; option.innerHTML=o.selectOptions[i]; if (o.defaultText==i) option.setAttribute('selected', 'selected'); ta.appendChild(option);}
        } else {
            var ta = document.createElement('textarea'); ta.setAttribute('name', o.parameterName); ta.setAttribute('rows', '4'); ta.value=o.defaultText;
            Event.observe(ta, 'keyup', function(e){expandTA(ta);}); Event.observe(ta, 'click', function(e){expandTA(ta);}); Event.observe(ta, 'focus', function(e){expandTA(ta);});
            if (typeof(o.maxlength)!='undefined') {ta.setAttribute('onkeyup', 'if(this.value.length>'+o.maxlength+') this.value=this.value.substring(0,'+o.maxlength+');');}
        }
        h.ta = ta; d.appendChild(ta); f.appendChild(d);
        var d = document.createElement('div');
        var submit = document.createElement('input'); submit.setAttribute('type', 'submit'); submit.setAttribute('value', LC.SAVE); submit.className='button';  d.appendChild(submit);
        d.appendChild(document.createTextNode(' or '));
        var cancel = document.createElement('input'); cancel.setAttribute('type', 'reset'); cancel.setAttribute('value', LC.CANCEL); cancel.className='discrete'; d.appendChild(cancel);
        // Opera didn't play nice with cancel from a link; had to do it with a form reset button. Don't know why.
        //var cancel = document.createElement('a'); cancel.setAttribute('href', '#'); cancel.setAttribute('onclick', 'return(false);'); cancel.appendChild(document.createTextNode('Cancel')); d.appendChild(cancel);
        //Event.observe(cancel, 'click', function(e){c.innerHTML=''; h.has_clicked=h.has_replaced=false; c.removeClassName('editable'); c.removeClassName('editableText');});
        f.appendChild(d); c.appendChild(f);  ta.focus();
    }
    var mouseover = function(e){
        if (h.has_clicked) return;
        h.replacedHTML = c.innerHTML;
        h.has_replaced = (o.defaultText.length==0);
        if (o.defaultText.length==0) {c.innerHTML=o.message; c.addClassName('editableText');}
        c.addClassName('editable');
    }
    var mouseout = function(e){
        if (h.has_clicked) return;
        if (h.has_replaced) c.innerHTML = h.replacedHTML;
        h.has_replaced = false;
        c.removeClassName('editable'); c.removeClassName('editableText');
    }
    Event.observe(c, 'click', click); Event.observe(c, 'mouseover', mouseover); Event.observe(c, 'mouseout', mouseout);
}

addHoverClass = function(cssIdentifier, hoverClassName) {
    $A($$(cssIdentifier)).each(function(element) {
	    Event.observe(element, 'mouseover', function(){$(element).addClassName(hoverClassName);});
	    Event.observe(element, 'mouseout', function(){$(element).removeClassName(hoverClassName);});
	});
}
document.observe('dom:loaded', function(){addHoverClass('.hoverable', 'hover');});
document.observe('dom:loaded', function(){addHoverClass('.button', 'hover');});
document.observe('dom:loaded', function(){addHoverClass('.submit', 'hover');});

function elementInsert(actionElement, toElement, location, force) {
    actionElement=$(actionElement);toElement=$(toElement);
    if (!actionElement || !toElement) return;
    if (location!='top') location='bottom';
    if (!actionElement||!toElement) {console.debug('Either actionElement or toElement was incorrectly defined in call to elementInsert'); return;}
    if(location=='bottom') toElement.appendChild(actionElement);
    else toElement.insertBefore(actionElement, toElement.firstChild);
}

function MarketMaker(b,q1,q2) {
    if(typeof(markerMakerOpposite)=='undefined' || !markerMakerOpposite) {
        this.b=new Number(b);this.q1=new Number(q1);this.q2=new Number(q2);
    } else {
        this.b=new Number(b);this.q1=new Number(q2);this.q2=new Number(q1);  // opposite
    }
    this.costHelper=function(q1,q2,b) {return(b*Math.log(Math.exp(q1/b)+Math.exp(q2/b)));}
    this.calc=function(quantity) {
        this.quantity=parseFloat(quantity);
        this.maxloss = Math.round(this.b*Math.log(2))*100;
        this.p1=Math.round(Math.exp(this.q1/this.b)/(Math.exp(this.q1/this.b)+Math.exp(this.q2/this.b))*10000.0)/100.0;
        this.p2=Math.round(Math.exp(this.q2/this.b)/(Math.exp(this.q1/this.b)+Math.exp(this.q2/this.b))*10000.0)/100.0;
        this.total = Math.round((this.costHelper(this.q1+this.quantity,this.q2,this.b)-this.costHelper(this.q1,this.q2,this.b))*10000.0)/100;
        this.price = this.total/Math.abs(this.quantity);
        this.avg = Math.round(10*this.total/this.quantity)/10;
        return(isNaN(this.total) ? 0 : (this.quantity>0 ? Math.ceil(this.total) : Math.floor(this.total)));
    }
    this.qFromTotal=function(cash) {
        var cash = parseFloat(cash)/100;
        var q = Math.floor(this.b * Math.log( Math.exp( (cash+this.q1)/this.b) + Math.exp( ( cash+this.q2)/ this.b) - Math.exp( this.q2/this.b ) ) - this.q1);
        this.calc(q);
        return(q);
    }
}

var MoreMenus = {
    build:function(container) {
        $(container).getElementsBySelector('li').each(function(li) {
                li = $(li); if (!li.getElementsByClassName('more-menu-popup').length) return; if (!li.getElementsByTagName('a').length) return;
                var menu = li.getElementsByClassName('more-menu-popup')[0]; var link = li.getElementsByTagName('a')[0];
                var div = $(document.createElement('div')); div.addClassName('more-menu-container');
                li.appendChild(div); div.appendChild(link); div.appendChild(menu);
                Event.observe(li, 'mouseover', function(e){MoreMenus.mouseover(e, div);});
                Event.observe(li, 'mouseout', function(e){MoreMenus.mouseout(e, div);});
                Event.observe(li, 'click', function(e){MoreMenus.click(e, div);});
                Event.observe(link, 'mouseover', function(e){MoreMenus.mouseout(e, div); Event.stop(e);});
                Event.observe(link, 'click', function(e){location.href=link.href; Event.stop(e);});
                $A(menu.getElementsByTagName('a')).each(function(a) {
                        Event.observe(a, 'click', function(e){location.href=a.href; Event.stop(e);});
                    });
            });
        Event.observe($$('body')[0], 'click', MoreMenus.destroy);
    },
    mouseover:function(event, el){el.addClassName('more-menu-container-hover');},
    mouseout:function(event, el){el.removeClassName('more-menu-container-hover');},
    click:function(event, el) {
        var menu = $(el.getElementsByTagName('ul')[0]); if (!menu) return;
        if(menu.style.display=='block') MoreMenus.destroy(); else MoreMenus.show(el, menu);
        Event.stop(event);
    },
    destroy: function() {$$('.more-menu-popup').each(function(popup) {popup.style.display='none';}); $$('.more-menu-container').each(function(container) {container.removeClassName('more-menu-container-selected')});},
    show: function(el, menu) {
        MoreMenus.destroy(); el.addClassName('more-menu-container-selected');
        var offset=Position.cumulativeOffset(el);  var dimensions=$(el).getDimensions();
        menu.setStyle({left:offset[0]+'px',top:(offset[1]+dimensions.height)+'px'}); menu.style.display='block';
    }
}

String.prototype.getHostname = function() {
    var re = new RegExp('^(?:f|ht)tp(?:s)?\://([^/]+)', 'im');
    try {
        return this.match(re)[1].toString();
    } catch(e) {
        return this.toString();
    }
} 

Event.observe(window, 'load', function() {   
   $$('a').each(function(e) { 
     if (e.innerHTML.length > 50) {
        e.innerHTML = e.innerHTML.getHostname() + '&hellip;'  
     }  
   }) 
}); //replace long links

/* STUFF FOR THE CONTRACT PAGE */
  function calcTotalPrice(frm, targetObj) {
    if (!frm) return;
        if (frm.price.value>100 || frm.price.value<1) return(false);
        var total = frm.price.value*frm.quantity.value;
        if (!isNaN(total) && frm.price.value.length>0 && frm.quantity.value.length>0 && frm.price.value>0 && frm.quantity.value>0) {
            targetObj.innerHTML = total;
            return(true);
        } else {
            targetObj.innerHTML = "-";
            return(false);
        }
  }

  function showProjection() {
        var frm = document.forms.buy;
        var total = frm.price.value*frm.quantity.value;
        var tbl = $('profitProjections');
        if (!isNaN(total) && frm.price.value.length>0 && frm.quantity.value.length>0 && frm.price.value>0 && frm.quantity.value>0) {
            $('profitProjection').innerHTML = frm.quantity.value * (100-frm.price.value);
            $('lossProjection').innerHTML = frm.quantity.value * (frm.price.value);

            tbl.style.display = '';
        } else {
            tbl.style.display = 'none';
        }
  }
  function inputHL(el, on) {
    if(on) Element.addClassName(el, 'cntoract-place-order-textbox-highlight'); else Element.removeClassName(el, 'contract-place-order-textbox-highlight');
  }

  function hlFirstOrderbookEntry(name, hl) {
    var el = $(name);
    if (el && el.getElementsByTagName('tr').length>0) {
       var tr = el.getElementsByTagName('tr')[0];
       var td = tr.getElementsByTagName('td');
       var a = tr.getElementsByTagName('a');
       if (hl) {
           for (var i=0; i<td.length; i++) Element.addClassName(td[i], 'highlightbackground');
           for (var i=0; i<a.length; i++) Element.addClassName(a[i], 'highlightbackground');
       } else {
           for (var i=0; i<td.length; i++) Element.removeClassName(td[i], 'highlightbackground');
           for (var i=0; i<a.length; i++) Element.removeClassName(a[i], 'highlightbackground');
       }
    }
  }
  function handleHelp(mode) {
      // reset other side
      if (mode=='buy_price' || mode=='buy_quantity') handleHelp('buy_form');
      if (mode=='sell_price' || mode=='sell_quantity') handleHelp('sell_form');

      // Buy form and help
      if (mode=='sell_form') {
          $('sellForm').show(); $('buyHelp').hide();
          hlFirstOrderbookEntry('booksells', false)
      }
      if (mode=='buy_price') {
          $('sellForm').hide(); $('buyHelp').show(); $('buyPriceToggle').show(); $('buyQuantityToggle').hide(); buildBuyPriceSlider();
          hlFirstOrderbookEntry('booksells', true)
      }
      if (mode=='buy_quantity') {
          $('sellForm').hide(); $('buyHelp').show(); $('buyPriceToggle').hide(); $('buyQuantityToggle').show(); buildBuyQuantitySlider();
          hlFirstOrderbookEntry('booksells', true)
      }

      // Sell form and help
      if (mode=='buy_form') {
          $('buyForm').show(); $('sellHelp').hide();
          hlFirstOrderbookEntry('bookbuys', false)
      }
      if (mode=='sell_price') {
          $('buyForm').hide(); $('sellHelp').show(); $('sellPriceToggle').show(); $('sellQuantityToggle').hide(); buildSellPriceSlider();
          hlFirstOrderbookEntry('bookbuys', true)
      }
      if (mode=='sell_quantity') {
          $('buyForm').hide(); $('sellHelp').show(); $('sellPriceToggle').hide(); $('sellQuantityToggle').show(); buildSellQuantitySlider();
          hlFirstOrderbookEntry('bookbuys', true)
      }
  }

  function updateBestBuyAndSell() {
      var s = (opposite_p ? orderbook.sellsopp : orderbook.sells);
      if (s.length) {
          $('bestBuyName').innerHTML = s[0].username;
          $('bestBuyQuantity').innerHTML = s[0].quantity;
          $('bestBuyPrice').innerHTML = Math.round(s[0].price);
          $('buyPriceHelpSuggestion').show();
      } else {
          $('bestBuyName').innerHTML = '';
          $('bestBuyQuantity').innerHTML = '';
          $('bestBuyPrice').innerHTML = '';
          $('buyPriceHelpSuggestion').hide();
      }

      var b = (opposite_p ? orderbook.buysopp : orderbook.buys);
      if (b.length) {
          $('bestSellName').innerHTML = b[0].username;
          $('bestSellQuantity').innerHTML = b[0].quantity;
          $('bestSellPrice').innerHTML = Math.round(b[0].price);
          $('sellPriceHelpSuggestion').show();
      } else {
          $('bestSellName').innerHTML = '';
          $('bestSellQuantity').innerHTML = '';
          $('bestSellPrice').innerHTML = '';
          $('sellPriceHelpSuggestion').hide();
      }
  }
  function setBuyForm(price, quantity) {
      if (typeof(price)!='undefined') document.forms.buy.price.value = (isNaN(price) ? '' : Math.round(price));
      if (typeof(quantity)!='undefined') document.forms.buy.quantity.value = Math.round(quantity) ;
      if (document.forms.buy.quantity.onkeyup) document.forms.buy.quantity.onkeyup();
  }
  function suggestBestBuy() {
      var s = (opposite_p ? orderbook.sellsopp : orderbook.sells);
      setBuyForm(s[0].price, s[0].quantity);
  }
  function setSellForm(price, quantity) {
      if (typeof(price)!='undefined') document.forms.sell.price.value = (isNaN(price) ? '' : Math.round(price));
      if (typeof(quantity)!='undefined') document.forms.sell.quantity.value = Math.round(quantity);
      if (document.forms.sell.quantity.onkeyup) document.forms.sell.quantity.onkeyup();
  }
  function suggestBestSell() {
      var b = (opposite_p ? orderbook.buydopp : orderbook.buys);
      setSellForm(b[0].price, b[0].quantity);
  }

// BUY SLIDERS
  function buildBuyPriceSlider() {
      slider = new Control.Slider('buyPriceHandle','buyPriceTrack', {range:$R(1,99)});
      slider.options.alignY = -30;
      slider.options.onSlide = slider.options.onChange = function(value) {
          $('buyPriceHandle').innerHTML = Math.round(value) + String.fromCharCode(160) + '%';
          setBuyForm(value, undefined);
      };
      // Get a reasonable price
      if (document.forms.buy.price.value.length && !isNaN(document.forms.buy.price.value)) {
          var p = document.forms.buy.price.value;
      } else {
          s = (opposite_p ? orderbook.sellsopp : orderbook.sells);
          var p = (s.length ? s[0].price : lastTrade);
      }
      // If quantity is set, we'll need to factor that in
      if (document.forms.buy.quantity.value.length && !isNaN(document.forms.buy.quantity.value)) {
          var q = document.forms.buy.quantity.value;
          var maxP = Math.floor(accountCash/q);
          if (maxP<p) p = maxP;
          slider.maximum = maxP;
      }
      slider.setValue(p);
      slider.options.onSlide(p);
  }
  function buildBuyQuantitySlider() {
      // Get a reasonable quantity
      if (document.forms.buy.quantity.value.length && !isNaN(document.forms.buy.quantity.value)) {
          var q = document.forms.buy.quantity.value;
      } else {
          s = (opposite_p ? orderbook.sellsopp : orderbook.sells);
          var q = (s.length ? s[0].quantity : 10);
      }
      // If price is set, we'll need to factor that in
      if (document.forms.buy.price.value.length && !isNaN(document.forms.buy.price.value)) {
          var p = document.forms.buy.price.value;
      } else {
          p = lastTrade;
          setBuyForm(p, undefined);
      }
      var maxQ = Math.floor(accountCash/p);
      if (maxQ>1000) maxQ = 1000;
      if (maxQ<q) q = maxQ;

      slider = new Control.Slider('buyQuantityHandle','buyQuantityTrack', {range:$R(1,maxQ)});
      slider.options.alignY = -30;
      slider.options.onSlide = slider.options.onChange = function(value) {
          $('buyQuantityHandle').innerHTML = Math.round(value) + String.fromCharCode(160) + 'stk';
          try {$('buyQuantityHandle').style.whiteSpace = 'no-wrap';} catch(e) {}
          setBuyForm(undefined, value);
      };
      slider.setValue(q);
      slider.options.onSlide(q);
  }

// SELL SLIDERS
  function buildSellPriceSlider() {
      slider = new Control.Slider('sellPriceHandle','sellPriceTrack', {range:$R(1,99)});
      slider.options.alignY = -30;
      slider.options.onSlide = slider.options.onChange = function(value) {
          $('sellPriceHandle').innerHTML = Math.round(value) + String.fromCharCode(160) + '%';
          setSellForm(value, undefined);
      };
      // Get a reasonable price
      if (document.forms.sell.price.value.length && !isNaN(document.forms.sell.price.value)) {
          var p = document.forms.sell.price.value;
      } else {
          s = (opposite_p ? orderbook.buysopp : orderbook.buys);
          var p = (s.length ? s[0].price : lastTrade);
      }
      // If quantity is set, we'll need to factor that in
      if (document.forms.sell.quantity.value.length && !isNaN(document.forms.sell.quantity.value)) {
          var q = document.forms.sell.quantity.value;
          var maxP = Math.floor(accountCash/q);
          if (maxP<p) p = maxP;
          slider.maximum = maxP;
      }
      slider.setValue(p);
      slider.options.onSlide(p);
  }
  function buildSellQuantitySlider() {
      // Get a reasonable quantity
      if (document.forms.sell.quantity.value.length && !isNaN(document.forms.sell.quantity.value)) {
          var q = document.forms.sell.quantity.value;
      } else {
          var q = accountBalance;
      }
      // If price is set, we'll need to factor that in
      if (document.forms.sell.price.value.length && !isNaN(document.forms.sell.price.value)) {
          var p = document.forms.sell.price.value;
      } else {
          p = lastTrade;
          setSellForm(p, undefined);
      }

      slider = new Control.Slider('sellQuantityHandle','sellQuantityTrack', {range:$R(1,accountBalance)});
      slider.options.alignY = -30;
      slider.options.onSlide = slider.options.onChange = function(value) {
          $('sellQuantityHandle').innerHTML = Math.round(value) + String.fromCharCode(160) + 'stk';
          try {$('sellQuantityHandle').style.whiteSpace = 'no-wrap';} catch(e) {}
          setSellForm(undefined, value);
      };
      slider.setValue(q);
      slider.options.onSlide(q);
  }


function buildOrderbookTable(container, data, formName, className, linkText, includeDelete) {
    if (typeof(includeDelete)=='undefined') includeDelete=false;
    var tbody = document.createElement('tbody');
    for (var i=0; i<data.length; i++) {
        var tr = document.createElement('tr');
        tr.className = (i/2==Math.floor(i/2) ? 'odd' : 'even');
        tr.setAttribute('id', 'ticket' + data[i].ticket_id);

        var td = document.createElement('td');
        td.className = 'contract-orderbook-table-username';
        var a = document.createElement('a');
        a.href = '/market/account/' + data[i].account_id;
        a.appendChild(document.createTextNode(data[i].username));
        td.appendChild(a);
        tr.appendChild(td);

        var td = document.createElement('td');
        td.className = 'contract-orderbook-table-number';
        td.setAttribute('align', 'center');
        td.appendChild(document.createTextNode(Math.round(new Number(data[i].quantity))));
        tr.appendChild(td);

        var td = document.createElement('td');
        td.className = 'contract-orderbook-table-value';
        td.setAttribute('align', 'center');
        td.appendChild(document.createTextNode(Math.round(new Number(data[i].price))))
        tr.appendChild(td);

        var td = document.createElement('td');
        td.className = 'contract-orderbook-table-delete';
        if (includeDelete) {
            if (data[i].account_id==account_id) {
                // My order, let me delete
                var a = document.createElement('a');
                a.setAttribute('href', "javascript:removeOrderbookItem("+data[i].ticket_id+", 'mylimitorders"+data[i].ticket_id+"', 'ticket"+data[i].ticket_id+"')");
                a.appendChild(document.createTextNode('Slet'));
                td.appendChild(a);
            } else {
                // Not mine...
                if (document.forms[formName]) {
                    // but I have shares, let me buy or sell
                    var a = document.createElement('a');
                    a.setAttribute('href', "#");
                    a.appendChild(document.createTextNode(linkText));
                    td.appendChild(a);
                    if (formName=='sell') {
                        var f = function(d,e){setSellForm(Math.round(new Number(d.price)), Math.round(new Number(d.price))); Event.stop(e); return(false);}
                    } else {
                        var f = function(d,e){setBuyForm(Math.round(new Number(d.price)), Math.round(new Number(d.price))); Event.stop(e); return(false);}
                    }
                    f=f.bind(this, data[i]);
                    Event.observe(td, 'click', f, true);
                }
            }
        }
        td.innerHTML += '&nbsp;';
        tr.appendChild(td);

        tbody.appendChild(tr);
    }
    tbody.setAttribute('id', container.getAttribute('id'));
    Effect.Fade(container, {afterFinish: function() {
        while (container.firstChild) container.removeChild(container.firstChild);
        Element.hide(tbody);
        container.parentNode.replaceChild(tbody, container);
        Effect.Appear(tbody);
    }});
}

    function updateOrderbook(includeDelete)  {
        if (typeof(includeDelete)=='undefined') includeDelete=true;
        if (!orderbook) return;

        if (typeof(graph)!='undefined' && graph!=null && graph.points && orderbook.last_trade && orderbook.last_trade.length) {
            var p = graph.points;
            p[p.length-1][INTERPOLATED_POINT] = p[p.length-1][POINT] = new String(opposite_p ? 100-orderbook.last_trade : orderbook.last_trade);
            p[p.length-1][VOLUME] = 1;
            graph.redraw();
        }

        var s = (opposite_p ? orderbook.sellsopp : orderbook.sells);
        if($('booksells')) buildOrderbookTable($('booksells'), s, 'buy', 'lightnegative', 'KÃ¸b', includeDelete)
        var b = (opposite_p ? orderbook.buysopp : orderbook.buys);
        if($('bookbuys')) buildOrderbookTable($('bookbuys'), b, 'sell', 'lightpositive', 'SÃ¦lg', includeDelete)

        updateBestBuyAndSell();

        if(typeof(placeItems)=='function') placeItems();
    }
function removeOrderbookItem(ticketID) {
    if (arguments.length>1) {
        for (var i=1; i<arguments.length; i++) {
            try {new Effect.Fade(arguments[i], {duration:.2});} catch(err) { }
        }
    }
    var params = "ticket_id="+encodeURI(ticketID);
    doAction('remove-limit-order', params);
}


// Javascript Sparklines Library. Written By John Resig. http://ejohn.org/projects/jspark/. Modified with min=0, max=100
function sparkline(o) {
  var p = o.innerHTML.split(',');
  while (o.childNodes.length > 0) {o.removeChild(o.firstChild);}
  var nw = "auto"; var nh = "auto";
  if (window.getComputedStyle) {nw = window.getComputedStyle( o, null ).width; nh = window.getComputedStyle( o, null ).height;}
  if (nw!="auto" ) nw = nw.substr(0,nw.length-2); if (nh!="auto" ) nh = nh.substr(0,nh.length-2);
  var f = 2; var w = ( nw == "auto" || nw == 0 ? p.length * f : nw - 0 ); var h = ( nh == "auto" || nh == 0 ? "1em" : nh );
  var co = document.createElement("canvas");
  if ( co.getContext ) o.style.display = 'inline'; else return false;
  co.style.height = h; co.style.width = w; co.width = w; o.appendChild( co ); var h = co.offsetHeight; co.height = h;
  var min = 0; var max = 100;
  if ( co.getContext ) {var c = co.getContext("2d"); c.strokeStyle = "#0273B4"; c.lineWidth = 1.0; c.beginPath(); for ( var i = 0; i < p.length; i++ ) {c.lineTo( (w / p.length) * i, h - (((p[i] - min) / (max - min)) * h) );} c.stroke();o.style.display = 'inline';}
}
function reloadSparklines() {$$('.sparkline').each(sparkline);}
Event.observe(window, 'load', reloadSparklines);


function alignHeight(elements) {
    if(elements.length<2) return;
    var h = 0;
    $A(elements).each(function(el){_h=$(el).getHeight(); if(_h>h) h=_h;});
    $A(elements).each(function(el){$(el).setStyle({'height':h+'px'})});
}


function setHtmlWithFade(c,val){
    if (Prototype.Browser.IE) {
        c.innerHTML = val;
        return;
    }
    var current = c.innerHTML;
    if(val==current) return;
    var col = (val>current ? '#04AC0E' : '#CC0000');
    new Effect.Morph(c, {style:{color:col}, duration:0.5, afterFinish:function(){
                c.innerHTML = val;
                new Effect.Morph(c, {style:{color:'#FFFFFF'}, duration:1});
            }});
}
function updateContracts(d,silent) {
    if (typeof(silent)=='undefined') silent=true;
    var id = d.contract_id;
    try {
        if(typeof(markerMakerContractId)!='undefined' && markerMakerContractId==id) {
            mm=new MarketMaker(d.b,d.q1,d.q2);
        }
    } catch(e){}

    
    
    var contract_id_found = false;


    var els = document.getElementsByClassName(['last_trade_',d.contract_id].join(''));
     for(i=0; i< els.length; i++) {       
            var el = els[i];
            contract_id_found = true;  //we actually try to update the rest
            var val = (el.getAttribute('rel')!='opposite' ? d.last_trade_nocurr : d.opposite_last_trade_nocurr);
            el.innerHTML = val;
    }

    if(contract_id_found) { //only try to update this contract, if its actually there.
        $$(['.last_change_',d.contract_id].join('')).each(function(el){
                var val_pretty = (el.getAttribute('rel')!='opposite' ? d.last_change_pretty : d.opposite_last_change_pretty);
                el.innerHTML = val_pretty;
                });
        $$(['.last_change_container_',d.contract_id].join('')).each(function(el){
                var val = (el.getAttribute('rel')!='opposite' ? d.last_change : d.opposite_last_change);
                    el.removeClassName('positive'); el.removeClassName('negative'); el.addClassName(val>=0 ? 'positive' : 'negative');
               });


        if (typeof(onLastTradeUpdate)=='function') onLastTradeUpdate(d);
        if (typeof(onLastChangeUpdate)=='function') onLastChangeUpdate(d);
    }



}
function cometContracts(msg) {
    updateContracts(dojo.fromJson(msg.data));
}

/* this should be a faster way to update the contracts on loadtime with 
   the jsonstruct

1. Get contracts on page.
2. For each contract, update .last_change_xxx, .last_change_container_xxx and .last_change_xxx

TODO
*/

function handlePreview(){
    $A($$('input.preview, textarea.preview')).each(function(element) {
            /*console.log(element);*/
            var _v = element.value;
            Event.observe(element, 'focus', function(){if(element.hasClassName('preview')) {element.removeClassName('preview'); element.value='';}});
            Event.observe(element, 'blur', function(){if(element.value.length==0) {element.addClassName('preview'); element.value=_v;}});
            element.up('form').observe('submit', function(e){if(element.hasClassName('preview')) {element.removeClassName('preview'); element.value='';}});
        });
}
document.observe('dom:loaded', handlePreview);


/*
  Lightbox w/ Prototype
  Based upon Lokesh Dhakar's Lightbox JS (See http://huddletogether.com/projects/lightbox/)

  This script is released by 23 (http://www.23hq.com) under  the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
  (Steffen Tiedemann Christensen, steffen@23hq.com, http://blog.23hq.com)

  Usage:
  lightbox('/myurl/demo.html');
  lightbox('/myurl/demo.html', {height:300, width:500});
  lightbox('/myurl/demo.html?test=yes', {left:10, top:10, height:300, width:500});
*/

function showLightbox() {
    // prep objects
    var objOverlay = $('overlay');
    var objLightbox = $('lightbox');

    objLightbox.style.overflow = lbOverflow;
    var viewport = document.viewport.getDimensions();
    var scroll = document.viewport.getScrollOffsets();

    objLightbox.setStyle({visibility:'hidden', display:'block'});

    if (lbH!=undefined) objLightbox.style.height = lbH + "px";
    if (lbW!=undefined) objLightbox.style.width = lbW + "px";
    if (lbY==undefined) {lbY = (scroll.top + (viewport.height-objLightbox.offsetHeight)/2);}
    if (lbX==undefined) {lbX = (scroll.left + (viewport.width-objLightbox.offsetWidth)/2);}
   
    objLightbox.setStyle({top:lbY+"px", left:lbX+"px", visibility:'visible'});
}


var lbX, lbY, lbW, lbH, lbOverflow;
function lightbox(target, P) {
    if (target==undefined) return;
    if (P==undefined) {var P = new Object();}
    var params = P.params; var h = P.height; var w = P.width; var x = P.left; var y = P.top; var overflow = P.overflow;

    if (overflow==undefined) {overflow = 'auto';}

    lbX = x;
    lbY = y;
    lbW = w;
    lbH = h;
    lbOverflow = overflow;

    initLightbox();

    // prep objects
    var objOverlay = $('overlay');
    var objLightbox = $('lightbox');

    // set height of Overlay to take up whole page and show
    objOverlay.setStyle({display:'block', height:document.viewport.getHeight()+'px', top:document.viewport.getScrollOffsets().top+'px'});

    new Ajax.Updater('lightbox', target, {method:'POST', postBody:params, onComplete:showLightbox, evalScripts:true});
}


function lightbox_inline(html_target, P) {
    if (html_target==undefined) return;
    if (P==undefined) {var P = new Object();}
    var params = P.params; var h = P.height; var w = P.width; var x = P.left; var y = P.top; var overflow = P.overflow;

    if (overflow==undefined) {overflow = 'auto';}

    lbX = x;
    lbY = y;
    lbW = w;
    lbH = h;
    lbOverflow = overflow;
    initLightbox();

    // prep objects
    var objOverlay = $('overlay');
    var objLightbox = $('lightbox');

    // set height of Overlay to take up whole page and show
    objOverlay.setStyle({display:'block', height:document.viewport.getHeight()+'px', top:document.viewport.getScrollOffsets().top+'px'});
    $('lightbox').update(html_target)
   showLightbox()
    //new Ajax.Updater('lightbox', target, {method:'POST', postBody:params, onComplete:showLightbox, evalScripts:true});
}




function hideLightbox(){
    // get objects
    var objOverlay = $('overlay');
    var objLightbox = $('lightbox');

    // hide lightbox and overlay
    objOverlay.hide();
    objLightbox.hide();
}

function initLightbox(){
    var objBody = document.getElementsByTagName("body").item(0);

    if (!document.getElementById('overlay')) {
	// create overlay div and hardcode some functional styles (aesthetic styles are in CSS file)
	var objOverlay = document.createElement("div");
	objOverlay.setAttribute('id','overlay');
	objOverlay.onclick = function () {hideLightbox(); return false;}
	objOverlay.style.display = 'none';
	objOverlay.style.position = 'absolute';
	objOverlay.style.top = '0';
	objOverlay.style.left = '0';
	objOverlay.style.zIndex = '90';
 	objOverlay.style.width = '100%';
	objBody.insertBefore(objOverlay, objBody.firstChild);
    }

    if (!document.getElementById('lightbox')) {
	// create lightbox div, same note about styles as above
	var objLightbox = document.createElement("div");
	objLightbox.setAttribute('id','lightbox');
	objLightbox.style.display = 'none';
	objLightbox.style.position = 'absolute';
	objLightbox.style.zIndex = '100';
	objBody.insertBefore(objLightbox, objOverlay.nextSibling);
    }
}
Event.observe(window, 'resize', function(){$$('#overlay').each(function(el){el.setStyle({height:document.viewport.getHeight()+'px', top:document.viewport.getScrollOffsets().top+'px'})})});

