// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

/*
- Ajax.InPlaceSelect.js -
  Creates a <select> control in place of the html element with the id
  specified.  It functions similar to "Ajax.InPlaceEditor" but instead
  of an <input> control, it creates a <select> control with a list of
  <options> from which to choose.  The parameters 'values' and 'labels'
  are arrays (of the same length) from which the <options> are defined.

- Syntax -
  new Ajax.InPlaceSelect('id', 'url', 'values[]', 'labels[]', { options });

- Example -
  new Ajax.InPlaceSelect('someId', 'someURL', [1,2], ['first','second'],
    { paramName: 'asset_type', parameters: "moreinfo=extra info" } );

- Options('default value') -
  - paramName('selected'): name of the default parameter sent
  - hoverClassName(null): class added when mouse hovers over the control
  - hightlightcolor("#FFFF99"): initial color (mouseover)
  - hightlightendcolor("#FFFFFF"): final color (mouseover)
  - parameters(null): additional parameters to send with the request
      (in addition to the data sent by default)
*/

Ajax.InPlaceSelect = Class.create();
Ajax.InPlaceSelect.prototype = {
  initialize:function(element,url,values,labels,options) {
    this.element = $(element);
    this.url = url;
    this.values = values;
    this.labels = labels;

    this.options = Object.extend({
      paramName: 'selected',
      highlightcolor: "#FFFF99",
      highlightendcolor: "#FFFFFF",
      onFailure: function(transport) {
        alert("Error: " + transport.responseText.stripTags());
      },
      savingText: "Saving...",
      savingClassName: 'inplaceeditor-saving',
      clickToEditText: "Double-click to edit",
      grouped: false
    }, options || {} );

    this.originalBackground = Element.getStyle(this.element, 'background-color');
    if (!this.originalBackground) {
      this.originalBackground = "transparent";
    }

    this.element.title = this.options.clickToEditText;

    this.ondblclickListener = this.enterEditMode.bindAsEventListener(this);
    this.mouseoverListener = this.enterHover.bindAsEventListener(this);
    this.mouseoutListener = this.leaveHover.bindAsEventListener(this);

    Event.observe(this.element, 'dblclick', this.ondblclickListener);
    Event.observe(this.element, 'mouseover', this.mouseoverListener);
    Event.observe(this.element, 'mouseout', this.mouseoutListener);
  },
  enterEditMode: function(evt) {
    if (this.saving) return;
    if (this.editing) return;
    this.editing = true;
    Element.hide(this.element);
    this.createControls();
    this.element.parentNode.insertBefore(this.menu, this.element);
    this.element.parentNode.insertBefore(this.cancelButton, this.element);
    return false;
  },
  createControls: function() {
    var options = new Array();
    if (this.options.grouped) {
      for (var i=0;i<this.values.length;i++) {
        var kiddies = new Array();
        for (var ki=0;ki<this.values[i].length;ki++) {
          kiddies[ki] = Builder.node('option', {value:this.values[i][ki]}, this.labels[i][ki])
        }
        if(this.options.groups[i]) {
          options[i] = Builder.node('optgroup', {label:this.options.groups[i]}, kiddies)
        } else {
          options[i] = Builder.node('optgroup', kiddies)
        }
      }
    } else {
      for (var i=0;i<this.values.length;i++) {
        options[i] = Builder.node('option', {value:this.values[i]}, this.labels[i]);
      }
    }
    this.menu = Builder.node('select', options);
    this.menu.onchange = this.onChange.bind(this);

    this.menu.onblur = this.onCancel.bind(this);
    //this.menu.onmouseout = this.onCancel.bind(this);

    if (this.options.grouped) {
      for (var i=0;i<this.menu.options.length;i++) {
        if (this.menu.options[i].text == this.element.innerHTML) {
          this.menu.selectedIndex=i;
          continue;
        }
      }
    } else {
      for (var i=0;i<this.values.length;i++)
        if (this.labels[i]==this.element.innerHTML) {
          this.menu.selectedIndex=i;
          continue;
        }
    }
    this.cancelButton = Builder.node('a', 'cancel');
    this.cancelButton.onclick = this.onCancel.bind(this);
  },
  onCancel: function() {
    this.onComplete();
    this.leaveEditMode();
    return false;
  },
  onChange: function() {
    var params = this.options.parameters + "&" + this.options.paramName + "=" + this.menu.options[this.menu.selectedIndex].value;
    this.onLoading();
    new Ajax.Updater({success:this.element}, this.url, {parameters: params,
      onComplete: this.onComplete.bind(this), onFailure: this.onFailure.bind(this)});
  },
  onLoading: function() {
    this.saving = true;
    this.removeControls();
    this.leaveHover();
    this.showSaving();
  },
  removeControls:function() {
    if(this.menu) {
      if (this.menu.parentNode) Element.remove(this.menu);
      this.menu = null;
    }
    if (this.cancelButton) {
      if (this.cancelButton.parentNode) Element.remove(this.cancelButton);
      this.cancelButton = null;
    }
  },
  showSaving:function() {
    this.oldInnerHTML = this.element.innerHTML;
    this.element.innerHTML = this.options.savingText;
    Element.addClassName(this.element, this.options.savingClassName);
    this.element.style.backgroundColor = this.originalBackground;
    Element.show(this.element);
  },
  onComplete: function() {
    this.leaveEditMode();
    new Effect.Highlight(this.element, {startcolor: this.options.highlightcolor});
  },
  onFailure: function(transport) {
    this.options.onFailure(transport);
    if (this.oldInnerHTML) {
      this.element.innerHTML = this.oldInnerHTML;
      this.oldInnerHTML = null;
    }
    return false;
  },
  enterHover: function() {
    if (this.saving) return;
    this.element.style.backgroundColor = this.options.highlightcolor;
    if (this.effect) { this.effect.cancel(); }
    Element.addClassName(this.element, this.options.hoverClassName)
  },
  leaveHover: function() {
    if (this.options.backgroundColor) {
      this.element.style.backgroundColor = this.oldBackground;
    }
    Element.removeClassName(this.element, this.options.hoverClassName)
    if (this.saving) return;
    this.effect = new Effect.Highlight(this.element, {
      startcolor: this.options.highlightcolor,
      endcolor: this.options.highlightendcolor,
      restorecolor: this.originalBackground
    });
  },
  leaveEditMode:function(transport) {
    Element.removeClassName(this.element, this.options.savingClassName);
    this.removeControls();
    this.leaveHover();
    this.element.style.backgroundColor = this.originalBackground;
    Element.show(this.element);
    this.editing = false;
    this.saving = false;
    this.oldInnerHTML = null;
  }
}
function initPage()
{
	var nav = document.getElementById("nav");
	if (nav)
	{
		var nodes = nav.getElementsByTagName("li");
		for (var i = 0; i < nodes.length; i++)
		{
			if (nodes[i].parentNode.id == "nav")
			{
				nodes[i].onmouseover = function () 
				{
					this.className += " hover";
				}
				nodes[i].onmouseout = function ()
				{
					this.className = this.className.replace(" hover", "");
				}
			}
		}
	}
}

if (window.attachEvent)
	window.attachEvent("onload", initPage);

defn_cache = {};

function updateDefinitions(request)
{
  var defns = eval("(" + request.responseText + ")");
  var elements = $$('.takesDefs');
  var i = 0;
  for (var idx=0; idx<elements.length; idx++) {
    var element = elements[idx];
    var subject = element.innerHTML;
    for (word in defns) {
      i += 1;
      subject = subject.replace(eval('/\\b('+word+')\\b/i'), '<a href="javascript:;" class="info" onmouseover="loadDefn(this)" name="defn_' + defns[word] + '">' +
                                                             '<span id="defn_tag_' + i + '">Loading...</span>$1</a>');
    }
    element.innerHTML = subject;
  }
}

function loadDefn(anchor)
{
  span = anchor.firstChild;
  defn = anchor.name.substr(5);
  anchor.onmouseover = null;
  if (defn_cache[defn]) {
    span.innerHTML = defn_cache[defn]
  } else {
    new Ajax.Updater(span.id, '/definition/meaning/' + defn, {
      onSuccess: function(request) { defn_cache[defn] = request.responseText }
    });
  }
}

