/**
*   @file
*   This file requires the following files to be included prior:
*
*   javascript/subclass.js
*   htmlelements/Mixin_DomInsertable.js
*   htmlelements/Mixin_HandlesEvents.js
*/


/**
*   This class will provide us basic button functionality.
*
*   @param name             The name of the object in the DOM we'll be creating.
*   @param id               The ID of the object in the DOM (Optional)
*   @param label            The text to be displayed on the button
*   @param onClick          Javascript to execute on click, as string.
*   @param toolTip          The text to be diaplayed in the tool tip for the button (Optional)
*   @param icon             The name of the icon to be displayed on the button (Optional)
*   @param buttonClass      The class (type) of button this is (Optional)
*                           Defaults to StyleButton.statics.Size["NORMAL"] is it is not set
*                           To create small buttons use StyleButton.statics.Size["SMALL"]
*/
subclass(StyleButton, Mixin_DomInsertable, Mixin_HandlesEvents);
function StyleButton(name, id, label, onClick, toolTip, icon, buttonClass)
{
    if(!id)
        id = name;  // Default.

    this.icon = icon;

    this.buttonClass = buttonClass;
    if(!buttonClass && 0!=buttonClass)
        this.buttonClass = StyleButton.statics.Size["NORMAL"];  // Default.

    Mixin_DomInsertable.call(this, "table", name, id);

    Mixin_HandlesEvents.call(this, onClick);

    // this only needs to be done for new buttons, clone
    if (label || icon)
    {
        this.DrawButton(label);

        if (toolTip)
            this.setToolTip(toolTip);
        else
            this.setToolTip(label);
        this.setLabel(label);

        this.SetButtonState(StyleButton.statics.State["NORMAL"]);
        var thisObject = this;
        this.SetOnMouseOver(function(){thisObject.SetButtonState(StyleButton.statics.State["OVER"])});
        this.SetOnMouseDown(function(){thisObject.SetButtonState(StyleButton.statics.State["DOWN"])});
        this.SetOnMouseOut(function(){thisObject.SetButtonState(StyleButton.statics.State["NORMAL"])});
        this.SetOnMouseUp(function(){thisObject.SetButtonState(StyleButton.statics.State["OVER"])});
    }
}


/**
*   Some constants used for the button
*/
StyleButton.statics = new Object();
StyleButton.statics.Size = {};
StyleButton.statics.Size["SMALL"] = 0;
StyleButton.statics.Size["NORMAL"] = 1;
StyleButton.statics.Size["SHORT"] = 2;
StyleButton.statics.State = {};
StyleButton.statics.State["NORMAL"] = 0;
StyleButton.statics.State["OVER"] = 1;
StyleButton.statics.State["DOWN"] = 2;


/**
*   This function fills the table with the elements required for it to look like a button.
*
*   @private
*/
StyleButton.prototype.DrawButton = function(hasLabel)
{
    // fill the table with what is needed for the button
    this.tableBodyNode = document.createElement("tbody")
    this.GetDomNode().appendChild(this.tableBodyNode);
    this.rowCellNode = document.createElement("tr");
    this.tableBodyNode.appendChild(this.rowCellNode);
    this.leftCapCellNode = document.createElement("td");
    this.rowCellNode.appendChild(this.leftCapCellNode);
    this.leftCapCellNode.className = 'leftCap';
    this.leftCapSpacerNode = document.createElement("img");
    this.leftCapCellNode.appendChild(this.leftCapSpacerNode);
    this.leftCapSpacerNode.className = 'spacer';
    if (this.icon && hasLabel)
    {
        this.iconCellNode = document.createElement("td");
        this.rowCellNode.appendChild(this.iconCellNode);
        this.iconCellNode.className = 'text icon';
        this.iconImageNode = document.createElement("img");
        this.iconImageNode.src = this.icon;
        this.iconCellNode.appendChild(this.iconImageNode);
        this.textCellNode = document.createElement("td");
        this.rowCellNode.appendChild(this.textCellNode);
        this.textCellNode.className = 'text textIconWidth';
    }
    else
    {
        this.textCellNode = document.createElement("td");
        this.rowCellNode.appendChild(this.textCellNode);
        if (!hasLabel && this.icon)
        {
          this.textCellNode.className = 'text icon';
        }
        else
        {
          if (StyleButton.statics.Size.SHORT == this.buttonClass)
            this.textCellNode.className = 'text textShort';
          else
            this.textCellNode.className = 'text';
        }
    }
    this.rightCapCellNode = document.createElement("td");
    this.rowCellNode.appendChild(this.rightCapCellNode);
    this.rightCapCellNode.className = 'rightCap';
    this.rightCapSpacerNode = document.createElement("img");
    this.rightCapCellNode.appendChild(this.rightCapSpacerNode);
    this.rightCapSpacerNode.className = 'spacer';
}


/**
*   This will return you a clone of the object.
*
*   @param name The new name for the cloned object
*   @param id   the new ID (Optional)
*/
StyleButton.prototype.Clone = function(name, id)
{
    // New button object
    var clone = new StyleButton(name, id);

    // Create a new node from the old.
    var clonedNode = this.GetDomNode().cloneNode(true);

    clonedNode.name = name;

    if(!id)
        id = clonedNode.name;

    clonedNode.id = id;

    clone.SetDomNode(clonedNode);
    clone.GetInternalDomNodes(clonedNode);

    // copy attributes to the new object
    clone.buttonClass = this.buttonClass;
    clone.setToolTip(this.getToolTip());
    clone.setLabel(this.getLabel());
    clone.icon = this.icon;
    clone.SetButtonState(StyleButton.statics.State["NORMAL"]);
    clone.SetOnMouseOver(function(){clone.SetButtonState(StyleButton.statics.State["OVER"])});
    clone.SetOnMouseDown(function(){clone.SetButtonState(StyleButton.statics.State["DOWN"])});
    clone.SetOnMouseOut(function(){clone.SetButtonState(StyleButton.statics.State["NORMAL"])});
    clone.SetOnMouseUp(function(){clone.SetButtonState(StyleButton.statics.State["OVER"])});

    return clone
}


/**
*   This function gets references to all of the internal dom nodes that make up the button.
*
*   @param node    The node to look in
*   @private
*/
StyleButton.prototype.GetInternalDomNodes = function(node)
{
    this.tableBodyNode = node.getElementsByTagName("tbody")[0];
    this.rowCellNode = this.tableBodyNode.getElementsByTagName("tr")[0];
    var cells = this.rowCellNode.getElementsByTagName("td");
    if (4==cells.length)
    {
        this.leftCapCellNode = cells[0];
        this.leftCapSpacerNode = this.leftCapCellNode.getElementsByTagName("img")[0];
        this.iconCellNode = cells[1];
        this.iconImageNode = this.iconCellNode.getElementsByTagName("img")[0];
        this.textCellNode = cells[2];
        this.rightCapCellNode = cells[3];
        this.rightCapSpacerNode = this.rightCapCellNode.getElementsByTagName("img")[0];
    }
    else if (3==cells.length)
    {
        this.leftCapCellNode = cells[0];
        this.leftCapSpacerNode = this.leftCapCellNode.getElementsByTagName("img")[0];
        this.textCellNode = cells[1];
        this.rightCapCellNode = cells[2];
        this.rightCapSpacerNode = this.rightCapCellNode.getElementsByTagName("img")[0];
    }
}


/**
*   Sets the css class of the button to correspond with the state.
*
*   @param state    One of the values from the StyleButton.statics.State array,]
*                   Defaults to StyleButton.statics.State["NORMAL"]
*/
StyleButton.prototype.SetButtonState = function(state)
{
    // find the base class for the button
    var buttonClass = 'button';
    if (StyleButton.statics.Size["SMALL"] == this.buttonClass)
        buttonClass = 'buttonSmall';

    // append the state class
    switch (state)
    {
        case StyleButton.statics.State["OVER"]:
            buttonClass = buttonClass+' '+buttonClass+'Over';
            break;
        case StyleButton.statics.State["DOWN"]:
            buttonClass = buttonClass+' '+buttonClass+'Down';
            break;
    }

    this.GetDomNode().className = buttonClass;
}


/**
*   This get the button's label text.
*/
StyleButton.prototype.getLabel = function()
{
    return this.label;
}


/**
*   This sets the button's label text.
*
*   @param l    The new label to be shown on the button
*/
StyleButton.prototype.setLabel = function(l)
{
    if (l)
    {
        this.label = l.replace(/ /g,'&nbsp;').replace(/-/g,'&#8209;');
        if (this.textCellNode)
        {
            if (this.icon)
                this.textCellNode.innerHTML = this.label + '&nbsp;';
            else
                this.textCellNode.innerHTML = this.label;
        }
    }
    else
    {
        this.label = null;
        if (this.textCellNode)
        {
            if (this.icon)
                this.textCellNode.innerHTML = '<img src="' + this.icon + '" alt="' + this.toolTip + '" />';
        }
    }
}


/**
*   This get the button's tooltip text.
*/
StyleButton.prototype.getToolTip = function()
{
    return this.toolTip;
}


/**
*   This sets the button's tooltip text.
*
*   @param t    The new label to be shown on the button
*/
StyleButton.prototype.setToolTip = function(t)
{
    this.toolTip = t;
    if (this.GetDomNode())
    {
        this.GetDomNode().title = this.toolTip;
    }
}
