var StudioDir = {};

StudioDir.okToSubmit = true;
StudioDir.pageLoaded = false;
StudioDir.submitEvents = [];

StudioDir.addOnLoadEvent = function(fn)
{
  if (window.onload)
  {
    var origOnLoad = window.onload;
    window.onload = function()
    {
      fn.call(window);
      origOnLoad.call(window);
    };
  }
  else
  {
    window.onload = fn;
  }
}

StudioDir.addOnLoadEvent(function()
{
  StudioDir.pageLoaded = true;
  StudioDir.resetOKToSubmit();
});

StudioDir.addSubmitEvent = function(fn)
{
  StudioDir.submitEvents.push(fn);
}

StudioDir.addEvent = function(elmt, eventName, fn)
{
  if (elmt.addEventListener)
  {
    elmt.addEventListener(eventName, fn, false);
  }
  else
  {
    elmt.attachEvent("on" + eventName, fn);
  } 
}

StudioDir.getel = function(id)
{
  var elmt;

  if (document.getElementById)
  {
    elmt = document.getElementById(id);
  } 
  else if (document.all)
  {
    elmt = document.all[id];
  } 
  else
  {
    elmt = null;
  }

  // for debugging only
  if (elmt == null)
  {
    //alert('StudioDir.getel - unable to find ' + id);
  }

  return elmt;
}

// DWR overrides this, so save the old one
StudioDir.encodeURIComponent = encodeURIComponent;

StudioDir.getAttrib = function(elmt, attrName)
{
  var attr;

  if (elmt[attrName])
  {
    return elmt[attrName];
  }
  else if (elmt.getAttribute)
  {
    return elmt.getAttribute(attrName);
  }
  else
  {
    return null;
  }
}

StudioDir.submitForm = function(form)
{
  if (StudioDir.pageLoaded == true)
  {
    StudioDir.okToSubmit = true;
    for (var i = 0; i < StudioDir.submitEvents.length; i++)
    {
      StudioDir.submitEvents[i]();
    }
    form.submit();
  }
  else
  {
    alert('You must wait for the page to finish loading.');
  }
}

StudioDir.onSubmit = function(page) 
{
  var pageElmt = StudioDir.getel('idPage');  
  if (pageElmt != null) // multi-part forms have no page
  {
    pageElmt.name = 'page';
    pageElmt.value = page;
  }
  StudioDir.submitForm(StudioDir.getel('idForm'));
}

StudioDir.onSubmitToMethod = function(page, meth) 
{
  StudioDir.getel('idMeth').name = 'meth';
  StudioDir.getel('idMeth').value = meth;
  StudioDir.onSubmit(page);
}

StudioDir.onCallMethodSubmit = function(page, meth, args)
{
  StudioDir.getel('idMethArgs').name = 'methargspost';
  StudioDir.getel('idMethArgs').value = args;
  StudioDir.onSubmitToMethod(page, meth);
}

/**
 * Used to prevent double clicking when submitting payment requests
 */
StudioDir.onSubmitThenSwitch = function(page, meth, span1, span2) 
{
  span2.className = 'displayblock';
  span1.className = 'displaynone';

  if (meth == null)
  {
    StudioDir.onSubmit(page);
  }
  else
  {
    StudioDir.onSubmitToMethod(page, meth);
  }
}

/**
 * Used to prevent double clicking when submitting payment requests
 */
StudioDir.onClickThenSwitch = function(url, span1, span2) 
{
  span1.className = 'displaynone';
  span2.className = 'displayblock';
  location.href = url;
}

StudioDir.onNEDSubmit = function(page, state) 
{
  StudioDir.getel('idPage').value = page;
  StudioDir.getel('idState').value = state;
  StudioDir.submitForm(StudioDir.getel('idForm'));
}

StudioDir.onSubmitToJspPageMethod = function(jsp, page, meth)
{
  var form = StudioDir.getel('idForm');
  form.action = jsp;
  StudioDir.getel('idPage').value = page;
  StudioDir.getel('idMeth').name = 'meth';
  StudioDir.getel('idMeth').value = meth;
  StudioDir.submitForm(form);
}

StudioDir.onSubmitCsv = function(page) 
{
  var form = StudioDir.getel('idForm');
  form.action = 'data.csv';
  StudioDir.getel('idPage').value = page;
  StudioDir.submitForm(form);
}

StudioDir.onSubmitToMethodCsv = function(page, meth) 
{
  StudioDir.onSubmitToJspPageMethod('data.csv', page, meth);
}

StudioDir.onSubmitToMethodPdf = function(page, meth) 
{
  StudioDir.onSubmitToJspPageMethod('data.pdf', page, meth);
}

StudioDir.submitFormOnEnter = function(evt)
{
  evt = (evt) ? evt : event;
  var target = (evt.target) ? evt.target : evt.srcElement;
  var form = target.form;
  var charCode = (evt.charCode) ? evt.charCode : ((evt.which) ? evt.which : evt.keyCode);

  if (charCode == 13 || charCode == 3)
  {
    StudioDir.submitForm(form);
    return false;
  }
  return true;
}

StudioDir.submitToMethodOnEnter = function(evt, page, meth)
{
  evt = (evt) ? evt : event;
  var target = (evt.target) ? evt.target : evt.srcElement;
  var form = target.form;
  var charCode = (evt.charCode) ? evt.charCode : ((evt.which) ? evt.which : evt.keyCode);

  if (charCode == 13 || charCode == 3)
  {
    StudioDir.getel('idPage').value = page;
    StudioDir.getel('idMeth').name = 'meth';
    StudioDir.getel('idMeth').value = meth;
    StudioDir.submitForm(form);
    return false;
  }
  return true;
}

/**
 * Replace all instances of string c with c2
 */
StudioDir.replaceAll = function(s, c, c2) 
{
  while (s.indexOf(c) != -1)
  {
    s = s.replace(c, c2);
  }
  return s;
}

StudioDir.doSearch = function()
{
  Search.search(StudioDir.getel('idSearchText').value, onSearchCallback);
}

StudioDir.doSearchOnEnter = function(evt)
{
  evt = (evt) ? evt : event;
  var target = (evt.target) ? evt.target : evt.srcElement;
  var charCode = (evt.charCode) ? evt.charCode : ((evt.which) ? evt.which : evt.keyCode);

  if (charCode == 13 || charCode == 3)
  {
    StudioDir.okToSubmit = false; // don't submit form if they press enter while focus is in search field
    StudioDir.doSearch();
  }
}

// Safari submits form when enter is pressed. We don't want it to do that when enter is pressed
// in the search field because we don't want it to go to another page. We also don't want it to
// submit if there is no default button because the page will not be set correctly.
// 
// Other browsers submit the form only if there is a default button. If not, okToSubmit stays false when
// you press enter with the focus in the search field. That is OK though because if there is no submit
// or image button, the only way you can submit the form is Javascript, and StudioDir.submitForm sets
// okToSubmit to true.
StudioDir.isOKToSubmit = function()
{
  if (StudioDir.pageLoaded == true)
  {
    var temp = StudioDir.okToSubmit;
    StudioDir.resetOKToSubmit();
    return temp;
  }
  else
  {
    return false;
  }
}

StudioDir.isSafari = function()
{
  return navigator != null && navigator.vendor != null && navigator.vendor.indexOf('Apple') != -1;
}

// Safari submits form when enter is pressed. If there is no default button (input type=submit or image),
// then we don't want it to submit so we set okToSubmit to false. If there is a default button, we set
// it to true. For the other browsers, just set it to true, because it will only submit the form if
// there is a default button.
StudioDir.resetOKToSubmit = function()
{
  if (StudioDir.isSafari())
  {
    if (StudioDir.hasDefaultButton == null)
    {
      StudioDir.hasDefaultButton = false;
      if (document.getElementsByTagName != null)
      {
        var elmts = document.getElementsByTagName("INPUT");

        for (var i = 0; i < elmts.length; i++)
        {
          var el = elmts[i];
          if (el.type == "image" || el.type == "submit")
          {
            StudioDir.hasDefaultButton = true;
            break;
          }
        }
      }
    }

    StudioDir.okToSubmit = StudioDir.hasDefaultButton;
  }
  else
  {
    // IE, firefox, and opera won't submit form if there is no default button, so this can always be true
    StudioDir.okToSubmit = true;
  }
}

/**
 * DWR does not like it if this is StudioDir.onSearchCallback
 */
function onSearchCallback(html) 
{
  StudioDir.getel('idSearchSpan').innerHTML = html;
}

/**
 * @param selElmt can be an id string, or the element itself
 * @param newValue string that will be compared against option values
 */
StudioDir.setSelectValue = function(selElmt, newValue) 
{
  if (typeof selElmt == 'string')
  {
    selElmt = StudioDir.getel(selElmt);
  }

  for (var i = 0; i < selElmt.options.length; i++)
  {
    var opt = selElmt.options[i];
    if (opt.value == newValue)
    {
      opt.selected = true;
    }
  }
}

/**
 * Sets a row in a FormEx table to visible or invisible.
 */
StudioDir.setFieldVisible = function(columnName, visible)
{
  var className = (visible ? 'visible' : 'invisible');
  StudioDir.getel(columnName + "__label").className = className;
  StudioDir.getel(columnName + "__field").className = className;
}

/**
 * Changes the label of a FormEx table
 */
StudioDir.changeLabel = function(columnName, newLabel)
{
  StudioDir.getel(columnName + "__label").innerHTML = '&nbsp;' + newLabel + '&nbsp;';
}

StudioDir.isValidDollarVal = function(x) 
{
  var dotFound = false;

  for (var i = 0; i < x.length; i++)
  {
    var c = x.charAt(i);
    if ('0' <= c && c <= '9')
    {
    } else if (c == '.')
    {
      if (dotFound)
      {
        return false;
      } else
      {
        dotFound = true;
      }
    } else
    {
      return false;
    }
  }

  return true;
}

String.prototype.trim = function() 
{
  return this.replace(/^\s+|\s+$/g,"");
}

StudioDir.Cal = {};

/**
 * @return Date object that represents value in __mon, __day, __year selects
 */
StudioDir.Cal.getSelectDate = function(colNamePrefix)
{
  var mon = StudioDir.getel(colNamePrefix + '__mon').value;
  var day = StudioDir.getel(colNamePrefix + '__day').value;
  var year = StudioDir.getel(colNamePrefix + '__year').value;

  if (mon == '' || day == '' || year == '')
  {
    return null;
  }
  else
  {
    return Date.parseDate(year + '-' + mon + '-' + day, '%Y-%e-%d');
  }
}

/**
 * Set the __mon, __day, and __year selects based on the date object.
 * 
 * Note, if you ever want to programatically change a calendar field,
 * you must write a function which calls setSelectDate and then sets
 * the hidden field, like updateHidden does.
 */
StudioDir.Cal.setSelectDate = function(colNamePrefix, date)
{
  StudioDir.setSelectValue(colNamePrefix + '__mon', date.print('%b'));
  StudioDir.setSelectValue(colNamePrefix + '__day', date.print('%e'));
  StudioDir.setSelectValue(colNamePrefix + '__year', date.print('%Y'));
}

/**
 * Updates the __hidden field when the selects change
 */
StudioDir.Cal.updateHidden = function(colNamePrefix)
{
  var hidden = StudioDir.getel(colNamePrefix + '__hidden');
  var date = StudioDir.Cal.getSelectDate(colNamePrefix);

  if (date != null)
  {
    hidden.value = date.print('%Y-%m-%d');
  }
}

StudioDir.Cal.closeCal = function(colNamePrefix, cal)
{
  StudioDir.Cal.setSelectDate(colNamePrefix, cal.date);
  cal.hide();
  return true;
}

StudioDir.Cal.dateSort = function(a, b)
{
  if (a.print('%Y-%m-%d,') < b.print('%Y-%m-%d,'))
  {
    return -1;
  }
  else if (a.print('%Y-%m-%d,') == b.print('%Y-%m-%d,'))
  {
    return 0;
  }
  else
  {
    return 1;
  }
}

StudioDir.Cal.closeMultiCal = function(colNamePrefix, cal, datea) 
{
  var hidden = StudioDir.getel(colNamePrefix + '__hidden');
  var selct = StudioDir.getel(colNamePrefix + '__select');

  datea.length = 0; // don't assign datea to new array because calendar still references old object
  for (var i in cal.multiple) 
  {
    var date = cal.multiple[i];
    if (date) 
    {
      datea[datea.length] = date;
    }
  }

  datea.sort(StudioDir.Cal.dateSort);

  // populate select and hidden
  selct.options.length = 0;
  hidden.value = '';
  for (var i = 0; i < datea.length; i++)
  {
    selct.options[selct.options.length] = new Option(datea[i].print('%b %d, %Y'));
    hidden.value += datea[i].print('%Y-%m-%d,');
  }

  // remove trailing comma
  if (hidden.value.length > 0)
  {
    hidden.value = hidden.value.substr(0, hidden.value.length-1);
  }

  cal.hide();
  return true;
}

StudioDir.Cal.dateStatusFunc = function(reservedDates, date)
{
  if (reservedDates[date.print('%Y-%m-%d')] == 1)
  {
    return true; // not selectable, return string for CSS style
  }
  return false;
}

StudioDir.Tooltip = {};

StudioDir.Tooltip.showTooltip = function(elmt, evt, type, args)
{
  var key = type.concat(args);
  var tooltipHtml = StudioDir.Tooltip.map[key];

  this.overElmt = elmt;

  if (tooltipHtml)
  {
    this.show(elmt, evt, tooltipHtml);
  }
  else
  {
    if (this.loading)
    {
      this.delayAndShow(elmt, evt, type, args);
    }
    else
    {
      this.load(elmt, evt, type, args);
    }
  }
}

StudioDir.Tooltip.delayAndShow = function(elmt, evt, type, args)
{
  window.setTimeout(function()
  {
    if (StudioDir.Tooltip.overElmt == elmt)
    {
      if (StudioDir.Tooltip.loading)
      {
        StudioDir.Tooltip.delayAndShow(elmt, evt, type, args);
      }
      else
      {
        StudioDir.Tooltip.load(elmt, evt, type, args);
      }
    }
  }, 100);
}

StudioDir.Tooltip.load = function(elmt, evt, type, args)
{
  this.loading = true;

  Tooltip.load(type, args, function(tooltipHtml)
  {
    var key = type.concat(args);
    StudioDir.Tooltip.map[key] = tooltipHtml;
    StudioDir.Tooltip.loading = false;

    // if mouse still over tooltip
    if (StudioDir.Tooltip.overElmt == elmt) 
    {
      StudioDir.Tooltip.show(elmt, evt, tooltipHtml);
    }
  });
}

StudioDir.Tooltip.show = function(elmt, evt, html)
{
  StudioDir.getel('tOoLtIpSpAn').innerHTML = html;
  this.ttShow(elmt);
  tt_Move(evt); // Work around so tooltip does not show in upper left corner.
                // tt_Show incorrectly uses the element instead of the event
                // when calculating the position. 
}

StudioDir.Tooltip.ttShow = function(elmt)
{
  tt_Show(elmt, 
          'tOoLtIp', 
          ttAbove,
          ttDelay,
          '',
          ttLeft,
          5, //ttOffsetX,
          5, //ttOffsetY,
          ttStatic,
          ttSticky,
          ttTemp);
}

StudioDir.Tooltip.hideTooltip = function()
{
  this.overElmt = null;
  tt_Hide();
}

StudioDir.Tooltip.init = function()
{
  this.map = {};
  this.loading = false;
  var tags = ['a'];

  for (var iTag = 0; iTag < tags.length; iTag++)
  {
    var tag = tags[iTag];
    var elmts = (document.getElementsByName ? document.getElementsByTagName(tag) : 
                                              (document.all ? document.all.tags[tag] : []));

    for (var iElmt = 0; iElmt < elmts.length; iElmt++)
    {
      var elmt = elmts[iElmt];
      var tipType = StudioDir.getAttrib(elmt, 'tipType');
      var tipArgs = StudioDir.getAttrib(elmt, 'tipArgs');

      if (tipType && tipArgs)
      {
        tipArgs = tipArgs.split(',');
        this.addEvents(elmt, tipType, tipArgs);
      }
    }
  }

  this.addSpan();
}

StudioDir.Tooltip.addEvents = function(elmt, tipType, tipArgs)
{
  elmt.onmouseover = function(evt)
  {
    StudioDir.Tooltip.showTooltip(elmt, 
                                  // copy the event because evt.pageX will get set to 0 
                                  // after event handler is called
                                  StudioDir.Tooltip.copyEvent(evt || window.event), 
                                  tipType, 
                                  tipArgs);
  };

  elmt.onmouseout = function(evt)
  {
    StudioDir.Tooltip.hideTooltip();
  };
}

StudioDir.Tooltip.addSpan = function()
{
  var props = new Object();
  props.T_BGCOLOR = '#ffffff';
  props.T_WIDTH = 0;

  var htm = tt_Htm(
    props,
    "tOoLtIp",
    "<span id=tOoLtIpSpAn></span>"
  );
  document.write(htm);

  if(document.getElementById)
  {
    tt_ifrm = document.getElementById("TTiEiFrM");
  }
}

StudioDir.Tooltip.copyEvent = function(evt)
{
  var copy = new Object();
  for (var prop in evt)
  {
    copy[prop] = evt[prop];
  }
  return copy;
}

StudioDir.debug = function(msg)
{
  StudioDir.getel('debuginfo').innerHTML = msg;
}

StudioDir.selectAction = function(selElmt)
{
  var url = selElmt.value; 
  selElmt.selectedIndex=0; 

  if (url != '') 
  {
    location.href = url;
  }
}

StudioDir.setStyle = function(elmt, styleName, styleValue)
{
  elmt.style[styleName] = styleValue;
}

