/**
 * Media Live Search Application, currently supporting searching from:
 *  - SAPO Fotos
 *  - Flickr
 *  - Google Images
 * 
 * A diffent concept for a different kind of media search
 * 
 * Features:
 *   - Live search of photos using diverse major media search engines as source
 *   - Saving some photos and deleting others from the pile
 *   - Sharing with others your own search slideshow
 * 
 * @author  Billy <voxmahina@gmail.com>
 * @version 0.1
 */
var Imagine = function (options)
{
  this.init(options);
};

Imagine.prototype = {
  /**
   * App Initialization
   * 
   * @param options a list of options
   */
  init: function (options)
  {
    this.options = jQuery.extend({
      rootUrl : 'http://dev.imagine.com/', 
      dom     : {
        class : {
          item : '.item'
        },
        id    : {
          search      : '#s',
          handler     : '#handler',
          header      : '#header',
          searchForm  : '#search',
          list        : '#list',
          more        : '#more',
          loader      : '#loader',
          msg         : '#msg',
          footer      : '#footer'
        }
      },
      animation : {
        framerate : 33 
      },
      menu : {
        closed : false
      },
      page     : 0,
      username : '',
      tag      : '',
      phase    : 0,
      start    : true
    }, arguments[0] || {});
    
    /* the current search tag and/or username */
    this._tag      = this.options.tag;
    this._username = this.options.username;
    
    /* try to set jquery framerate to a more cpu friendly value */
    jQuery.fx.interval = this.options.animation.framerate;
    
    /* start */
    this.onReady();
  },
 /**
  * Clears the image list
  */
  clearList : function ()
  {
    jQuery(this.options.dom.id.list).html('');
  },
 /**
  * Closes the top menu
  */
  closeMenu : function ()
  {
    var header  = jQuery(this.options.dom.id.header),
        handler = jQuery(this.options.dom.id.handler),
        speed   = 300;
        
    if (this.options.phase < 1) {
      speed              = 2000;
      this.options.phase = 1;
    }        
    
    header.slideUp(speed);
    handler.animate({
      top : '0'
    }, speed);
    this.options.menu.closed = true;
  }, 
 /**
  * Fill
  */  
  fill : function ()
  {
    var data, 
        container = jQuery(this.options.dom.id.list), 
        clean     = false,
        more      = jQuery(this.options.dom.id.more);
    
    /* fill */
    if (arguments[0] !== undefined) {
      data  = arguments[0];
      clean = true;
    } else {
      data = this._data;
    }
    
    /* check */
    if (data.length < 0) {
      this.showEmptyResults();
    } else {
      var title, smallTitle, desc, link, source, html, img;
      
      /* close menu and clear list */
      if (clean) {
        this.options.page = 1;
      } else {
        /* update page number */
        this.options.page++;
      }
      
      this.hideLoader();
      
      for (var i=0; i<data.length; i++) {
      
        smallTitle = title  = data[i].title, 
        desc       = data[i].description, 
        link       = data[i].link, 
        source     = data[i].src;
      
        /* fix big titles */  
        if (title.length > 30) {
          smallTitle = title.substring(0, 30) + '...';
        }
        if (desc.length > 300) {
          desc = desc.substring(0, 300) + '...';
        }
      
        /* show */
        if (source !== '') {
          html = "<li class='item'><a class='popover' href='"+link+"' title='Open in a new tab' " 
               + " target='_blank'><img src='"+source+"' alt='' border='0' /><p>"+smallTitle+"</p></a>"
               + "<span style='display:none;'>"+title+"<br /><br />"+desc+"</span></li>";
          container.append(html);
        }
        
      }
      /* clean */
      delete data;      
      /* show more button */
      more.find('span').html('load more');
      more.show();
    }
  },
 /**
  * Hide loader
  */ 
  hideLoader : function ()
  {
    jQuery(this.options.dom.id.loader).hide();
  }, 
 /**
  * jQuery onDocumentReady handler
  */ 
  onReady : function (e) 
  {
    var _this          = this, 
         sBox          = jQuery(this.options.dom.id.search),
         header        = jQuery(this.options.dom.id.header),
         handler       = jQuery(this.options.dom.id.handler),
         searchForm    = jQuery(this.options.dom.id.searchForm),
         loader        = jQuery(this.options.dom.id.loader),
         msg           = jQuery(this.options.dom.id.msg);
         
    /* remove no-js class from html */
    jQuery('html').removeClass('no-js').addClass('js-active');
    
    /* show, center and add events handler to top menu handler */
    handler
      .css("left", ((jQuery(window).width() - 81) / 2) + jQuery(window).scrollLeft() + "px")
      .show()
      .click(function (e) {
        e.preventDefault();
        _this.toggleMenu();
      });
         
    /* search input handler */
    sBox.focus(function (e) {
      if (sBox.val() == 'search...') {
        sBox.val('');
      }
    }).blur(function (e) {
      if (sBox.val() == '') {
        sBox.val('search...');
      }
    }).parent().find('a').click(function (e) {
      e.preventDefault();
      _this.search();
    });
    
    searchForm.submit(function (e) {
      e.preventDefault();
      _this.search();
    });
    
    /* more button */
    jQuery(this.options.dom.id.more).click(function (e) {
      e.preventDefault();
      jQuery(_this.options.dom.id.more).find('a').addClass('mloader');
      /* fetch */
      jQuery.post('/ajax', {s:_this._tag, u:_this._username, p:++_this.options.page}, function (data) {
        if (data.length > 0) {
          _this._data = data;
          _this.fill();
          jQuery(_this.options.dom.id.more).find('a').removeClass('mloader');
        } else {
          _this.showEmptyResults();
        }
      });
    });
    
    /* live item hover/out */
    jQuery(this.options.dom.class.item).live('mouseenter', function (e) {
      jQuery(this).find('span')
        .css({width : jQuery(this).width()})
        .show();
        jQuery(this).find('p').hide();
    }).live('mouseleave', function (e) {
      jQuery(this).find('span').hide();
      jQuery(this).find('p').show();
    });
    
    /* on window scroll */
    jQuery(window).scroll(function () {
      var offset  = jQuery(this).scrollTop();
      header.css({
        'position' : 'absolute',
        'top'      : offset + 'px',
        'width'    : '100%',
        'opacity'  : '0.97'
      });
    });
    
    /* update loader position */
    loader.css({
      position : 'absolute',
      top      : ((jQuery(window).height() - 48) / 2) + jQuery(window).scrollTop() + "px",
      left     : ((jQuery(window).width() - 48) / 2) + jQuery(window).scrollLeft() + "px"
    });
    
    /* update msg position */
    msg.css({
      position : 'absolute',
      top      : ((jQuery(window).height() - 40) / 2) + jQuery(window).scrollTop() + "px",
      left     : ((jQuery(window).width() - 250) / 2) + jQuery(window).scrollLeft() + "px"
    });
    
    /* start searching now? */
    if (this.options.start) {
      this.search();
    }
  },
 /**
  * Opens the top bar menu
  */  
  openMenu : function ()
  {
    var header  = jQuery(this.options.dom.id.header),
        handler = jQuery(this.options.dom.id.handler);
        
    header.slideDown();
    handler.animate({
      top : '141px'
    });
    this.options.menu.closed = false;
  },
 /**
  * Search
  */ 
  search : function ()
  {
    var _this  = this, 
        sValue = jQuery(this.options.dom.id.search).val(), 
        footerMsg;
    
    /* a new search? */
    if (this.options.page < 1 || jQuery(this.options.dom.id.search).val() != this._tag) {
      jQuery(this.options.dom.id.more).hide();
      jQuery(this.options.dom.id.msg).hide();
      this.clearList();
      this.showLoader();
      this.closeMenu();
      if (this.options.tag !== '' && sValue == 'search...') {
        this._tag = this.options.tag;
      } else if (this.options.username !== '') {
        this._username = this.options.username;
        this._tag      = jQuery(this.options.dom.id.search).val();
        footerMsg = 'now showing flickr photos from user: \''+this._username+'\'';
        if (this._tag !== '' && this._tag !== 'search...') {
          footerMsg += ' related with \''+this._tag+'\'';
        }
      } else {
        this._tag = jQuery(this.options.dom.id.search).val();
        if (sValue !== 'search...') {
          footerMsg = 'now showing flickr photos related with \''+this._tag+'\'';
        }
      }
      /* update top menu to fixed */
      jQuery(this.options.dom.id.handler).css({position:'fixed'});
      /* update footer msg */
      this.updateFooter(footerMsg);
    }
    
    /* search */
    jQuery.post('/ajax', {s:this._tag, u:this._username}, function (data) {
      if (data.length > 0) {
        _this.fill(data);    
      } else {
        _this.options.page = 0;
        _this.showEmptyResults();
      }
    });
  },
 /**
  * show empty results warning
  */
  showEmptyResults : function ()
  {
    if (this.options.page < 1) {
      this.hideLoader();
      this.showMsg('no results');
      this.openMenu();
    } else {
      var more      = jQuery(this.options.dom.id.more),
          container = more.find('span').html('no more results');
      container.html('no more results');
      more.find('a').removeClass('mloader');
      more.show().delay(2000).fadeOut();
    }
  }, 
 /**
  * Show loader
  */ 
  showLoader : function ()
  {
    jQuery(this.options.dom.id.loader).show();
  },
 /**
  * Shows a message
  */
  showMsg : function (msg)
  {
    jQuery(this.options.dom.id.msg)
      .html(msg).show().delay(2000).fadeOut();
  },  
 /**
  * Toogles the top bar menu
  */
  toggleMenu : function ()
  {   
    if (this.options.menu.closed !== false) { /* open */  
      this.openMenu();
    } else { /* close */
      this.closeMenu();
    }
  },
 /**
  * Update footer message
  */
  updateFooter : function (msg) {
    jQuery(this.options.dom.id.footer).html(msg);
  }
}
