// ---------------------------------------------------------------------------
// (c) 2003 Geotalk, Hans Martin Mohn
// ---------------------------------------------------------------------------
//
// Add member variables and methods to the DOM element representing an IMG so
// that the IMG behaves like a button.
//
// Dependencies:
//
//    None
//
// Parameters:
//
//    element       The DOM element representing the IMG
//    image_down    The name of the image to display when the button is down.
//                  The image will be looked for in the same directory as the
//                  original image.
//    image_active  The name of the image to display when the mouse is inside the button.
//                  Or null if the button shouldn't change
//    tooltip       The string to display as a tooltip for the button.
//    action        Javascript source code to execute when the button is clicked.
//    disabled      Optional flag: if true, the button will start up in the disabled state
//    disabled_tip  Optional string: explanation of why button is disabled
//
// Example:
//
//    gtBeButton(btnSave, "btnSaveDown.png", null, "Save", "map.saveDirtyObjects()", true);

function gtBeButton(element, image_down, image_active, tooltip, action, disabled, disabled_tip)
{
  // When this function is called by the onload() method of an image, we will be called twice -
  // First when the "up"-image has loaded and then again for the "down"-image!
  if (typeof(element.m_image_up) != "undefined")
    return;

  // Add event handlers first. This installs default no-op handlers which are overridden below!
  addGTHandlers(element);
  element.style.cursor = (disabled) ? "auto" : "pointer";

  // All member attributes are set AFTER the member functions!
  // (so that we can call member functions while setting attributes...)



  element.replaceTooltipText = function gtButton_replaceTooltipText(text)
  {
    var a = this.m_replacement_array;
    for (var i = 0; i < a.length; i += 2)
      text = text.replace(new RegExp(a[i], "g"), a[i + 1]);
    return text;
  }; // end replaceTooltipText()



  element.setTooltipReplacements = function gtButton_setTooltipReplacements(replacement_array)
  {
    this.m_replacement_array = replacement_array;
    this.setTooltipToShow();
  }; // end setTooltipReplacements()



  element.setDisabled = function gtButton_setDisabled(val, explanation)
  {
    this.m_disabled = val;
    if (val)
      this.m_explanation = explanation;
    else
      this.m_explanation = "";

    this.showButtonDisabled(this.m_disabled || this.m_busy);
    this.setTooltipToShow();
    this.style.cursor = (this.m_disabled) ? "default" : "pointer";
  }; // end setDisabled()



  element.setBusy = function gtButton_setBusy(val)
  {
// gtTraceLine("setBusy: " + val);
    this.m_busy = val;
    this.showButtonDisabled(this.m_disabled || this.m_busy);
  }; // end setBusy()



  element.setTooltipToShow = function gtButton_setTooltipToShow()
  {
    this.title = this.m_tooltip;
    if (this.m_disabled && this.m_explanation)
      this.title += " (" + this.m_explanation + ")";
    if (this.m_replacement_array)
      this.title = this.replaceTooltipText(this.title);
  }; // end setTooltipToShow()
  


  element.showButtonDisabled = function gtButton_showButtonDisabled(disabled)
  {
    var transparency = (disabled) ? 0.7 : 0.0;
    gtSetTransparent(this, transparency);
//    this.style.backgroundColor = (disabled) ? "#ccc" : "";
  }; // end showButtonDisabled()



  element.doAction = function gtButton_doAction()
  {
//top.gtTrace("gtMouseUp: " + m_action + "\n");
    eval(this.m_action + (this.m_action_has_parameters ? "," : "") +  this.m_button_down + ")"); // Do whatever this button is supposed to to!
  }; // end doAction()



  element.gtMouseDown = function gtButton_gtMouseDown(evt)
  {
    if (this.m_disabled || this.m_busy || this.m_button_down)
      return false;
    this.m_button_down = true;
    this.src = this.m_image_down;
    gtCancelBubble(evt);
    return gtPreventDefault(evt); // no default action
  }; // end gtMouseDown()



  element.gtMouseUp = function gtButton_gtMouseUp(evt)
  {
    if (this.m_disabled || this.m_busy)
      return false;

    if (this.m_button_down)
      this.doAction();
      
    this.m_button_down = false;
    this.src = this.m_image_active ? this.m_image_active : this.m_image_up;
    gtCancelBubble(evt);
    return gtPreventDefault(evt); // no default action
  }; // end gtMouseUp()



  element.gtMouseOver = function gtButton_gtMouseOver(evt)
  {
    if (this.m_disabled || this.m_busy)
      return false;
    if (this.m_image_active && !this.m_button_down)
      this.src = this.m_image_active;
    gtCancelBubble(evt);
    return gtPreventDefault(evt); // no default action
  }; // end gtMouseOver()



  element.gtMouseOut = function gtButton_gtMouseOut(evt)
  {
    if (this.m_image_active !== null)
      this.src = (this.m_button_down) ? this.m_image_down : this.m_image_up;
    gtCancelBubble(evt);
    return gtPreventDefault(evt); // no default action
  }; // end gtMouseOut()



  // Suppress dragging!
  element.gtDragStart = function gtButton_gtDragStart(evt)
  {
    gtCancelBubble(evt);
    return gtPreventDefault(evt); // no default action
  }; // end gtDragStart()



  element.changeImages = function gtButton_changeImages(up, down, active, tooltip)
  {
    this.m_tooltip      = tooltip;
    this.m_image_up     = this.m_img_path + up;
    this.m_image_down   = this.m_img_path + down;
    this.m_image_active = (active) ? this.m_img_path + active : null;
    this.src = this.m_image_up;
    this.setTooltipToShow();
  }; // end changeImages()



  element.decodeActionString = function gtButton_decodeActionString()
  {
    // Dissect the action-string to find the method name - we will call it with true or false as parameter
    // Typical action:
    //   onCommand('cmdSetEditLock')
    // In order to pass state info to the action function, we append a true/false parameter like so:
    //   onCommand('cmdSetEditLock', true)
    var b_par = this.m_action.lastIndexOf("(");
    var e_par = this.m_action.lastIndexOf(")");
    if (b_par > 0 && e_par > 0)
    {
      if (e_par - b_par > 1)
        this.m_action_has_parameters = true;
      else
        this.m_action_has_parameters = false;
      element.m_action = element.m_action.substring(0, e_par); // Chop off everything from last ")" and to the end
    }
  }; // end decodeActionString()



  // ====================================
  // Now we can set the member attributes
  // ====================================

  var slash_pos = element.src.lastIndexOf("/");
  element.m_img_path          = (slash_pos < 0) ? "" : element.src.substr(0, slash_pos + 1);
  element.m_image_up          = element.src;
  element.m_button_down       = false;
  element.m_disabled          = false;  // Must be set explicitly (in order to be instantiated??)
  element.m_busy              = false;
  element.m_action            = action;
  element.m_tooltip           = tooltip;
  element.m_replacement_array = null;
  element.title               = tooltip;

  element.m_image_down = element.m_img_path + image_down;
  if (image_active !== null)
    element.m_image_active = element.m_img_path + image_active;
  else
    element.m_image_active = null;

  if (typeof(disabled) != "undefined")
    element.setDisabled(disabled, disabled_tip);

  element.decodeActionString();
} // end addBtnHandlers()


