/*
 * Input Floating Hint Box - jQuery plugin 1.1 Beta
 *
 * Copyright (c) 2008 Nicolae Namolovan (nicolae.namolovan gmail.com)
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: 20
 *
 */
 /**
  * Home page http://nicolae.namolovan.googlepages.com/jquery.inputHintBox.html
  * Demo http://nicolae.namolovan.googlepages.com/jquery.inputHintBox.demo.html
  **/

/**
 * Provide an automatic box hint in the right side of a input when user click it, it disapear when focus change (blur)
 *
 * Depends on dimensions plugin's offset method for correct positioning of the hint box element
 *
 * The source(@source) of the text/html can be an attribute (title for example), or a pure html.
 * Attribute can contain escaped html, example: title="This will be &lt;b&gt;Bold&lt;/b&gt;"
 *
 * All hints can use one div element(@div option) with your custom design, and only some subelement of 
 * this @div will change (according to source).
 *
 * You can provide only the @className, and for each input a separate <div> element will be created
 * with @className as class.
 *
 * If user click on the box to select some text (for copy/paste for example), box will not disappear.
 *
 * If you need to make the box appear in more left, use incrementLeft, same for top - incrementTop,
 * you can use - sign if you want to decrement.
 **/

/**
 * Example, you have a shiny div and you want to use it as a Shell for hint messages
 * <div id="shiny_box">
 *   <span id="round-tleft"><span id="round-tright">
 *  <div class="shiny_box_body"></div>
 *   <span id="round-bleft"><span id="round-bright">
 * </div>
 *
 * You have a inputs like:
 * <input name="username" type="text" class="titleHintBox" title="Only letters &lt;b&gt;(a-z)&lt;/b&gt;, numbers (0-9), and periods (.) are allowed">
 * <input name="password" type="text" class="titleHintBox" title="Minimum of 8 characters in length">
 *
 * Here is an example of js to use:
 * $J('.titleHintBox').inputHintBox({div:$J('#shiny_box'),div_sub:'.shiny_box_body',source:'attr',attr:'title',incrementLeft:12,incrementTop:-12});
 **/

/**
 * Provide a hint box near input as a absolute positioned div.
 * @name InputHintBox
 * @cat Plugins/Forms
 * @type $J
 * @param Map options Optional settings
 * @option jQueryDom @div box to show, if this is set then className do not apply
 * @option String @div_sub css selector, use this when you need to write the Dynamic html into a element Inside the @div box,
               example: .body, this will search for .body in context of @div
 * @option String @className This class will be added to the dynamic created div box. Default: "input_hint_box"
 * @option String @source Source of box message text html: attr | html, Default: "attr"
 * @option String @attr If @source = "attr" then html will be taken from the attribute named @attr. Default: "title"
 * @option String @html If @source = "html" them html will be taken from @html
 * @option Integer @incrementLeft This value will be incremented to the left property of the absolute positioned hint box. Default: 10
 * @option Integer @incrementTop This value will be incremented to the top property of the absolute positioned hint box. Default: 10
 * @option String @attachTo Hint box will be appended to this. Default: "body"
 */

(function($J) {
$J.fn.inputHintBox = function(options) {
  options = $J.extend({}, $J.inputHintBoxer.defaults, options);
  
  this.each(function(){
    new $J.inputHintBoxer(this,options);
  });
  return this;
}

$J.inputHintBoxer = function(input, options) {
  var $JguideObject,$Jinput = $JguideObject = $J(input), box, boxMouseDown = false;

  //$JguideObject - in left of this object hint box will be positioned
  
  // If @type=radio then it must be inside a label and we should put the hint box in the right side of the label
  if ( ($Jinput.attr('type') == 'radio' || $Jinput.attr('type') == 'checkbox') && $Jinput.parent().is('label') ) {
    $JguideObject = $J( $Jinput.parent() );
    //$JguideObject = $J(body.document);
  }
  

  function init() {
    var boxHtml = options.html != ''?options.html:
              options.source == 'attr'?$Jinput.attr(options.attr): '';
      
    if (typeof boxHtml === "undefined") boxHtml = '';
    box = options.div != '' ? options.div.clone() : $J("<div/>").addClass(options.className);
    box = box.css('display','none').addClass('_hintBox').appendTo(options.attachTo);
    
    if (options.div_sub == '') box.html(boxHtml);
    else $J(options.div_sub,box).html(boxHtml);
    
    $Jinput.focus(function() {
      $J('body').mousedown(global_mousedown_listener);
      show();
    }).blur(function(){
      prepare_hide();
    });
    
    /*$Jinput.click(function() {
      $J('body').mousedown(global_mousedown_listener);
      show();
    }).blur(function(){
      prepare_hide();
    });*/
  }
  
  // This is evaluated each time to prevent probs with elements with display none
  function align() {
    var offsets = $JguideObject.positionProperty(),
      left = offsets.left + ($J.browser.msie?257:$JguideObject.width()) + options.incrementLeft + ($J.browser.safari?5:($J.browser.msie?10:($J.browser.mozilla?6:0))),
      top = offsets.top + options.incrementTop + ($J.browser.msie?8:($J.browser.mozilla?8:0));
    box.css({position:"absolute",top:top,left:left});
  }
  
  function show() {
    align();
    box.fadeIn(500);
  }
  
  function prepare_hide() {
    // We want to allow user to select and copy/paste content from the box
    // So delay a bit to see where user click
    $J('body').click(global_click_listener);
    if (boxMouseDown) return;
    $J.inputHintBoxer.mostRecentHideTimer = setTimeout(function(){hide()},100);
  }
  
  var global_click_listener = function(e) {
    var $Je = $J(e.target),c='._hintBox';
    clearTimeout($J.inputHintBoxer.mostRecentHideTimer);
    if ($Je.parents(c).length == 0 && $Je.is(c) == false) hide();
  };
  
  // Prevent hiding when selecting..
  // When user Select a text to select, a Mousedown is fired BEFORE blur of input
  // This why we need to know when a Mousedown is done to our object
  var global_mousedown_listener = function(e) {
    var $Je = $J(e.target),c='._hintBox';
    boxMouseDown = ($Je.parents(c).length != 0 || $Je.is(c) != false);
  }
  
  function hide() {
    $J('body').unbind('click',global_click_listener);
    $J('body').unbind('mousedown',global_mousedown_listener);
    align();
    box.fadeOut(200);
  }
  
  init();
  return {}
};

$J.inputHintBoxer.mostRecentHideTimer = 0;

$J.inputHintBoxer.defaults = {
  div: '',
  className: 'input_hint_box',
  source: 'attr', // attr or html
  div_sub: '', // Where to write
  attr: 'title',
  html: '',
  incrementLeft: 0,
  incrementTop: 0,
  attachTo: 'body'
}

})(jQuery);

