// TODO: took out icon slopply, namely, just killed the elemnet style that was keeping the text from overlapping it.
/**
 * Tool tip, alert boxes.  A work in progress.
 *
 *
 *  eg: feedback.warn_box.show('oh no! error!') (global feedback var is introduced.)
 *      $(...).toolTip("I'm a helpful hint!");
 *   
 *   include jquery.corners.js to get round corners on your tooltips
use a style something like this:
.tool-tip 
{
          padding:6px;
          background-color: #22857f; 
          color: white; 
          border:solid 1px #FFFFFF; 
          font-size:small;
          text-align: center;
}
 */ 
var toolTip = {
          className: "tool-tip",
          cornerRadius: 2,
          align:"left",
          orient: "above",
          width: 100,
          borderWidth:0,
          arrowHeight: 7,
          showCallback: function(settings) {if(settings.borderBox) settings.borderBox.fadeIn('fast');$(this).fadeIn('fast')}
};
$.fn.toolTip = function(msg,options) {
  options = options || {};
  var timeout = options['timeout'] || 0;
  this.hover(
    function() {
      $(this).data('tool-tip',true);
      setTimeout( 
        (function($sel) {
          return function() {
            if($sel.data('tool-tip')) {  $sel.callout($.extend({}, toolTip,options,{'text':msg})); }
          };
        })($(this)), timeout
      );
    },
    function() {
      $(this).data('tool-tip',false)
             .closeCallout();
    }
  );
}

/**
 * 
 *  settings can be given (precedence lowest to highest)
 *    1) in the template markup for the box, in a div with the id "options".  The contents must be valid object literal notation, without the {}
 *    2) at run-time, to the constructor
 *    3) at run-time, to show() //todo This doesn't work with callbacks? Seem to just dissapear from the options array passed in.. hmmm...
 *
 *  Looks for an element '#tempaltes .feedback' for a default template
 *
 *  settings.mode :
 *    notify : just presenting information, clicking it makes it go away
 *    notify-auto : mouse movement after a certain min time (settings.minTime) makes it go away
 *    ...more to come
 */ 
function Alerter(options) {
 var settings = {
                  style: {
                      position:'fixed', top: 0, left: 0,
                      opacity:0
                   }, 
                   width:0, height:0, /* 0 means auto-size */ 
                   noHide: false, /* helps with debugging monolog (auto-hiding) styles with tools like firebug */
                   noIcon: false,
                   containerClass: '',
                   mode: 'notify-auto', /* see comments above */
                   place: 'upper-right',
                   goodpic : '/img/yes.png',
                   badpic : '/img/no.png',
                   template: null, /* selector of div containg template markup.  null to try defaults. */
                   id:null,
                   minTime:1000, /* for notify-auto */
                   /* call backs */
                   onShowing: function() {}, // box is begins to show
                   onShown: function() {}, // box is completly visible
                   onExit: function() {},  // box begins to hide
                   onGone: function() {}  // box is completly gone
                } 
  if(options==undefined) options = {};
  var current_settings = {}; // stores per-use variations ( per show() )
                 

  

  // grab template markup or use default
  var template = options.template || settings.template;

  if(!template) template = '#templates .feedback'; // will try a default selector
  template = $(template).html();
  if(!template) template =  '<div><div class="feedback-title"></div><div class="feedback-body"></div></div>';

  // pull additional options from template, inside a id=options div
  var $template = $(template);
  var markup_settings = $template.find('#options');
  if(markup_settings) {
    markup_settings = markup_settings.text();
    $template.find('#options').remove();
    if(markup_settings) {
      markup_settings = eval('[{'+markup_settings+'}]').pop(); 
    } else markup_settings = {};
  }

  // run-time options overide settings in markup, which overrid defaults
  $.extend(true, settings, markup_settings, options);
  if(settings.containerClass) $template.addClass(settings.containerClass);

  // create box element
  try {
    $msgbox = $template.css(settings.style);
    $msgbox.css({'z-index':999999});
  } catch(err) {
    throw('Could not convert contents of template container.  Bad markup or more than one immediate child in container?');
  }
  if(settings.id) $msgbox.attr('id',settings.id);
  $('body').append($msgbox);

  // shortcuts
  $msgtitle = $msgbox.find('.feedback-title');
  $msgbody = $msgbox.find('.feedback-body');
  $msgicon = $msgbox.find('.feedback-icon');

  /* follow scroll... todo
  $(window).scroll(function() {
    $msgbox.css({'top':$(window).scrollTop()});  
  });
  */

  var control_hide = settings.mode == 'notify-auto'; // some modes need to prevent hiding
  var hide_ok = control_hide ? false : true; // co-ord. min show time w/ mouse move hide event
  var shown = false; 

  // The public object
  var obj = (function(settings, $msgbox, $msgtitle, $msgicon) {
    return {
      show : function(title,body,options) {
        if(shown) return;
        current_settings =  options || {};
        $.extend(true,current_settings, settings);

        var good = (current_settings.good || current_settings.good == undefined ) ? true : false;

        // todo: danger, un-reviewed old code ahead
        var pic = good ? current_settings.goodpic : current_settings.badpic;
        if(!current_settings.noIcon) $msgicon.html('<img align=top src="'+pic+'" height="30px" width="30px"/>');

        $msgtitle.html(title || '');
        $msgbody.html(body || '');
        that = this;
        $msgbody.find('.hide-box').click(function(){that.requestHide()});
        

        if(control_hide) hide_ok = false;
        shown = true;

        var style;
        // Box placements
        switch(current_settings.place) {
          case('upper-right'):
            style = {top:$(window).scrollTop(), right:0};
            break;
          case('middle'):
            style = {
                      top: $(window).height()/2 - ($msgbox.outerHeight()/2),
                      left:$(window).width()/2 - ($msgbox.outerWidth()/2)
                    };
            break;
          // TODO: leaving off here for today...
        }
        
        // rmbr to call above current_settings.onShown if you add new callbacks here
        var cb = control_hide ?
             function() {
                setTimeout(function() {hide_ok = true}, current_settings.minTime);
                current_settings.onShown();
             } : current_settings.onShown;
       
        raos.log($msgbox.outerHeight());
        $msgbox.find('.notice-shadow-box').height($msgbox.outerHeight()).width($msgbox.outerWidth()).css({'top':5,'left':5});
        $msgbox
          .css(style)
          .fadeTo('slow', 1, cb);


        current_settings.onShowing();
        return $msgbox;
      },
      // hide if min time has elapsed, called by body mouse move if notify-auto
      requestHide : function() {
        if(shown && hide_ok && !current_settings.noHide) this.hide();
      },
      hide: function() {
        if(shown) {
          if(control_hide) hide_ok = false; // when called by requestHide (notify-auto mode), ensures we only do this once
          $msgbox.fadeTo('slow', 0, function() {shown=false; $msgbox.css({'left':-1000});current_settings.onGone();});
          current_settings.onExit();
        }
      }
    }
  })(settings, $msgbox, $msgtitle, $msgicon);

  if(settings.mode == 'notify-auto') {
    $('body').mousemove(function() {
      obj.requestHide();
    });
  }

  return obj;
}

// Demo "global" object to use on page.  Would normally customize (extend) per app.
var feedback;

$(function() {

feedback  =  {
  notice : new Alerter(),
  asker : new Alerter({mode:'notify'}),
  /* warn: new Alerter({clspfx:'warning',place:'mid'}), */
  say : function(ttl,bdy,opts) {return feedback.notice.show(ttl,bdy,opts)},
  ask : function(ttl,bdy,opts) {return feedback.asker.show(ttl,bdy+'<div class="msg-box-ask" style="text-align:center"><a class="hide-box">No Thanks</a></div>',opts)}
}

});

