(function() {
  /* You also need to include the bar stylesheet present at /css/newbase.css */

var $ = jQuery;
var LimeBar;

window.LimeBar = LimeBar = function(elem, options) {
  var self = this;
  this.element = $(elem);
  this.bit = null;
  this.bitObj = null;
  
  this.options = $.extend({
    bit: null,
    showPageTabs: false,
    mode: 'platform',
    bitfinderContextManaged: false,
    messageHandler: function(e) { },
    limebar: this,
    links : []
  }, options);

  this.element.append(
   '<div class="limebits">                    \
       <div class="barBody ui-widget ui-widget-content">                                                        \
          <div class="limeLogo"><a></a></div>                                        \
          <div class="mysites"><a class="mysites">My Sites</a></div> \
          <div class="userNav">                                                      \
            <span class="username spacer inActiveText">NiceTim</span>                \
            <a class="help spacer ui-links-header">Help</a>                               \
            <a class="account ui-links-header" title="Change password or email">Account</a>               \
            <a class="signout ui-links-header">Sign out</a>                               \
            <a class="signin ui-links-header">Sign in</a>                          \
            <a class="join ui-links-header">Join</a>                                      \
          </div>                                                                     \
          <div class="pageNav">                                                \
              <span class="bitName"></span>                                         \
              <a class="getbit ui-priority-primary" title="Copy">Copy this Site and Remix!</a> \
              <a class="view" title="Show site in new window">View Site&nbsp;<span class="ui-icon-popout" style="display:inline-block; margin: 0px 0px -2px 0px; padding: 0;"></span></a> \
              <a class="newMix" title="Create a new site">Mix New Site</a>             \
              <a class="more" title="More options">More<span class="ui-icon ui-icon-triangle-1-s" style="display:inline-block; margin-bottom:-4px; margin-right: -6px;"></span></a>             \
   		      <ul id="myMenu" class="contextMenu">        \
    			<li><a href="#settings" >Site Settings</a></li>        \
    			<li><a href="#source" >Show Source Code</a></li>        \
                <li><a href="#hidesource" >Hide Source Code</a></li>        \
    			<li><a href="#labs" >Show Lab Features</a></li>        \
                <li><a href="#findbits" >Find Stuff for My Sites</a></li>        \
                <li><a href="#duplicate" >Duplicate Site</a></li>        \
    			<li><a href="#delete" >Delete Site</a></li>        \
		      </ul>        \
          </div>                                                                     \
          <div class="bitFinder">                                                    \
            <a class="newMix" title="Create a new site">Mix New Site</a>             \
            <a class="findbits" title="Find stuff to copy">Find Stuff for My Sites</a>             \
          </div>                                                                     \
        </div>                                                                       \
    </div>'
  );
  // Make all links jquery buttons
  jQuery.each(this.element.find('.bitFinder a, .pageNav > a, a.mysites'), function(){ self.makeJQueryButton(jQuery(this)); } );
  
  this._setupLogoLink();
  this._setupBitfinderLinks();
  this._setupNewMixLink();
  this._setupPagenavLinks();
  this._setupUsernavLinks();
  this._setupBitmarks();
  this._setupGetBit();
  this._setupCommandListener();
  
  if (this.options.bit)
    {
      AXIS.Login.onAuthUpdate.subscribe({
        callback: function() {
          if (arguments.callee.fired) return;
          arguments.callee.fired = true;

          self.handleCommand({
            cmd: 'bitChanged',
            cmdArgs: self.options.bit
          });
        }
      });
      
    }

  AXIS.Login.onAuthUpdate.subscribe({
    callback: function(e) {
        var user = e.data || 'unauthenticated';
        if (user != 'unauthenticated') {
            self.handleCommand({
                cmd: 'setLimebarState',
                cmdArgs: 'max' // default is max only for authenticated users
            });
        }
        
        self.handleCommand({
            cmd: 'setMode',
            cmdArgs: self.options.mode
        });
    }
  });


};

LimeBar.prototype = {

  dropshadowHeight: 8,

  /* TODO: change to function */
  galleryPathPref : AXIS._siteData.hosts.limebits + 'apps/bitfinder/#tag=Site&url=/',

  /* TODO: change to function */
  editorPathPref: AXIS._siteData.hosts.limebits + 'apps/editor/#',
  
  bitmixPathPref: AXIS.Bits.Utils.domainize('/apps/bitmix/index.html?bar', {
      limeroot: true,
      owner: AXIS.User.username()
  }),
            

  maxDescriptionLength: 60,

  maxNameLength: 40,

  handleCommand: function(o) {
    var self = this;
    switch(o.cmd) {

    case "contextChange":
    
      var highlightedLink = "none";
      var context = o.cmdArgs;
      if(context) {
        highlightedLink = context.isOwner ? "mybits" : "findbits";
      }
      self.selectBitfinderLink(highlightedLink);

      break;

    case "bitChanged":
      this.bit = AXIS.Util.bit.bitInfo(AXIS.Util.uri.getBitUrl(o.cmdArgs));
      // the bitfinder does not have same options as all the other bits, sites, apps, etc
      // AND the bitmix is not exactly a "bit"
      if ( self.options.mode != 'bitfinder' && this.bit.tld_root.indexOf('apps/bitmix') == -1 ) 
     {
        this.bitObj = AXIS.Bits.get(this.bit.tld_root);
        this.element.trigger('bitChanged');
     }
      break;

    case "setMode":
      this.setMode(o.cmdArgs);
      break;

    case "setLimebarState":
      this.setLimebarState(o.cmdArgs);
      break;

    case "refresh":
        top.location.href = o.cmdArgs;
        break;

     case "updatePage":
        self.element.find('a.view').attr('href', self.bit.url + '?nobar#page=' + o.cmdArgs);
         break;
        
     case "talkToParent":
         if (jQuery.postMessage) {
             var target = decodeURIComponent(location.hash.slice(1).split('&')[0]);
             jQuery.postMessage(o.cmdArgs, target, parent);
         }
         break;
    
    }

  },
  
  _setupLogoLink: function() {
    var self = this;
    self.element.find('.limeLogo a, a.mysites').attr('href', AXIS._siteData.hosts.limebits);
  },

  _setupNewMixLink: function() {
      var self = this;
        
      AXIS.Login.onAuthUpdate.subscribe({
        callback: function(e){
            var user = e.data || 'unauthenticated';
            if (user == 'unauthenticated') {
                self.element.find('a.newMix').click(function(e){
                    e.preventDefault();
                    AXIS.Login.forceLogin = true;
                    AXIS.Login.redirReturnTo = AXIS._siteData.hosts.limebits.replace(/www/, '!user') + "!lime/root/apps/bitmix/index.html?bar";
                    AXIS.Login.inUserDomain = true;
                    AXIS.Login.login();
                });
            }
            else {
                self.element.find('a.newMix').attr("href", AXIS._siteData.hosts.limebits.replace(/www/, user) + "!lime/root/apps/bitmix/index.html?bar");
                    /**
                     * We need to reload page if we click newSite within bitmix, but IE does it anyway...
                     */
                    if( self.mode == 'bitmix' && !AXIS.isIE )
                    {
                        top.location.reload(true);
                    }
            }
        }
      });   
  },
  
  _setupBitfinderLinks: function() {
    var self = this;

    self.element.find('.bitsNav').css('display', 'inline');

    self.element.find('a.findbits').click(function(){
        var url = self.galleryPathPref;
        self.refresh(url);
    });

  },

  _setupUsernavLinks: function() {
    var self = this;

    self.element.find("a.join").attr("href", AXIS._siteData.hosts.secure + 'secure/access.html#sign_up=1');
    self.element.find("a.signin").attr("href", AXIS._siteData.hosts.secure + 'secure/access.html');
    self.element.find("a.account").attr("href", AXIS._siteData.hosts.secure + 'secure/profile.html');
    self.element.find("a.help").attr("href", AXIS._siteData.hosts.limebits.replace("www", "bits") + 'help/');

    self.element.find(".join, .signin, .username, .signout, .account").css('display', 'none');

    AXIS.Login.onAuthUpdate.subscribe({
      callback: function(f) {
        var user = f.data;
        self.user = user;
        self.element.find(".join, .signin, .username, .signout, .account").hide();

        if (user) {
          self.element.find(".username").text(user);
          self.element.find(".username, .account, .signout").css('display', 'inline');
        } else {
          self.element.find(".join, .signin").css('display', 'inline');
        }
        self.element.trigger('authChanged');
      }
    });

    self.element.find("a.signin").click(function(e) {
      if (self.options.signin_destination == "workspace")
        return;

      e.preventDefault();
      AXIS.Login.forceLogin = true;
      if (self.bit && self.options.mode != 'source')
        AXIS.Login.redirReturnTo = self.bit.url;

      AXIS.Login.login();
    });

    self.element.find("a.signout").click(function(e) {
        AXIS.Login.onAuthUpdate.unsubscribeAll(); // dont want other subscribers to mess things up...
        AXIS.Login.afterLogout.subscribe({
            callback: function(){
                self.options.messageHandler({
                    cmd: "signedOut"
                });
                self.handleCommand({
                    cmd: 'setLimebarState',
                    cmdArgs: 'reset'
                });
                self.refresh(AXIS._siteData.hosts.limebits);
            }
        });
        AXIS.Login.logout();
    });

  },

  _setupPagenavLinks: function() {
    var self = this;

    if (AXIS.Util.lang.inArray(self.options.mode, ['source', 'view', 'bitmix'])) {
        self.element.find('.pageNav').show();
        self.element.find('.bitFinder').hide();
        self._setupMoreMenu();
    }
    else
    {
        self.element.find('.pageNav').hide();
        self.element.find('.bitFinder').show();
    }

    self.element.find('a.view').click(function(e) {
        var url = self.bit.url.replace("?bar", "");
        url += self.bitObj.getOwner() == AXIS.User.username() ? '?nobar' : '?bar';
        self.refresh(url);
    });

    self.element.bind('bitChanged', function(){
        if (AXIS.Util.lang.inArray(self.options.mode, ['view', 'bitmix'])) {
            self.element.find('a.view').attr('href', self.bit.url + '?nobar');
            self.element.find('a.view').attr('target', self.bitObj.getBitFolderName());
            self.element.find('a.view').unbind('click');
            
            // say "view full" if we're in view mode, or if we're viewing a non-site
            if (self.options.mode == 'view' || !self.bitObj.hasTag('Site') )
                self.element.find('a.view').html(self.element.find('a.view').html().replace('Site', 'Full'));
        }
    });
  },
  
  _setupMoreMenu: function() {
      var self = this;
      self.element.find('.more').contextMenu({
        menu: 'myMenu'
    }, function(action){
            /**
             * Weird bug... in IE8, the contextMenu returns action with hash symbol within
             */
            if(action.indexOf('#') > -1)
            {
                action = action.substring(action.indexOf('#') +1);
            }
            switch(action) {
                case "source":
                    var url = self.editorPathPref + self.bit.tld_path;
                    self.refresh(url);
                	break;
                
                case "hidesource":
                    // extremely hacky code... we dont know where we came from, so guess.
                    if(document.referrer.indexOf('bitfinder') == -1) 
                    {
                        // we could have come from viewer or bitmix... but there is no viewer with bar for owner of site.
                        if( self.bitObj.getOwner() == AXIS.User.username() )
                        {
                            self.refresh(self.bitmixPathPref + "#bm_project=" + encodeURIComponent(self.bit.tld_root.split('/home/'+self.bit.owner)[1]));    
                        }
                        else
                        {
                            self.refresh(self.bit.url);
                        }
                    }
                    else
                    {
                        self.refresh(document.referrer);
                    }
                break;
                
                case "delete":
                    self.bitObj.remove({
                        callback: function(){
                            self.refresh(AXIS._siteData.hosts.limebits);
                        }
                    });
                    break;
                
                case "findbits":
                    self.refresh(self.galleryPathPref);
                    break;
                    
                case "labs":
                    var action, labBtn = self.element.find('.pageNav a[href*=#labs]');
                    if (labBtn.text().indexOf('Hide') > -1) {
                        labBtn.text(labBtn.text().replace('Hide', 'Show'));
                        action = 'bitMixLabs_disable';
                    }
                    else {
                        labBtn.text(labBtn.text().replace('Show', 'Hide'));
                        action = 'bitMixLabs_enable';
                    }
                    self.handleCommand({
                        cmd: 'talkToParent',
                        cmdArgs: action
                    });
                    break;

                case "duplicate":
                    AXIS.Bits.Utils.getBit(self.bitObj.getLocation(), false);
                break;
            }
    });
    
    self.element.find('#myMenu li').hide();

    self.element.bind('bitChanged', function(){
        var showMenuItem = function(id){
            self.element.find('#myMenu a[href*=#' + id + ']').parent().show();
        };
        
        switch (self.options.mode) {
            case "view":
                showMenuItem('source');
                showMenuItem('findbits');
                break;
                
            case "source":
                showMenuItem('hidesource');
                showMenuItem('findbits');
                showMenuItem('settings');
                showMenuItem('labs');
                showMenuItem('duplicate');
                showMenuItem('delete');

                self.element.find('#myMenu').disableContextMenuItems('#settings,#labs');
                if (self.bitObj.getOwner() != AXIS.User.username()) {
                    self.element.find('#myMenu').disableContextMenuItems('#duplicate,#delete');
                }
                break;
                
            case "bitmix":
                showMenuItem('settings');
                showMenuItem('source');
                showMenuItem('labs');
                showMenuItem('findbits');
                showMenuItem('duplicate');
                showMenuItem('delete');
                self.element.find('#myMenu').disableContextMenuItems('#settings');
                break;
        }
    });
    
    self.element.find('.more').click(function(e){
        e.stopPropagation();
        self.options.messageHandler({
            cmd: "fullscreen",
            cmdArgs: "on"
        });
        var id = setInterval(function(){
            if (!self.element.find('#myMenu').is(":visible")) {
                self.options.messageHandler({
                    cmd: "fullscreen",
                    cmdArgs: "off"
                });
                clearInterval(id);
            }
        }, 10);
    });
  },
  
  _setupBitmarks: function() {
    var self = this;
    self.element.find('.bitName').hide(); // dont show by default
    
    self.element.bind('bitChanged', function() {
         if (AXIS.Util.lang.inArray(self.options.mode, ['source', 'view', 'bitmix'])) {
             var name = self.bitObj.getDisplayName();
             if (name && name != 'bitmix') {
                 if (name.length > self.maxNameLength) 
                     name = name.slice(0, self.maxNameLength) + "...";
                 self.element.find('.bitName').text(name);
                 self.element.find('.bitName').show();
             }
         }
    });
  },

  _setupGetBit: function() {
    var self = this;
    self.element.find('a.getbit').hide();
    
    self.element.find('a.getbit').click(function(e) {
        e.preventDefault();

        if (self.bitObj.hasTag('Site')) {
            AXIS.Bits.Utils.getBit(self.bitObj.getLocation(), false, self.bitmixPathPref);
        }
        else
        {
            AXIS.Bits.Utils.getBit(self.bitObj.getLocation(), false);
        }
    });

    self.element.bind('bitChanged', function() {
        if(self.bitObj.hasTag('Site') == false)
        {
            self.element.find('a.getbit').text('Copy this bit');    
        }
        self.element.find('a.getbit').attr("href", self.bit.url);

        if (self.bitObj.getOwner() != AXIS.User.username() ) 
            self.element.find('a.getbit').show();
    });

  },

  selectBitfinderLink: function(link) {
    var self = this;
    
    self.element.find('.'+link).addClass('ui-state-active').addClass('selected');
  },

  hidePageTabs: function() {
    var self = this;

    self.element.removeClass('bitBackground');
    self.element.find('.underBar').hide();
    self.element.find('.pageNav a').hide();
  },

  setMode: function(mode) {
    var self = this;

    self.options.mode = mode;
    
    self.options.messageHandler({
      cmd: 'refreshHeight'
    });
  },

  getBarHeight: function(dropshadow) {
    var self = this;

    var height = self.element.height();

    if (dropshadow === false && self.element.find('.underBar').is(':visible'))
      height -= self.dropshadowHeight;

    return height;
  },

  refresh: function(newLocation) {
    var self = this;

    self.handleCommand({
        cmd: 'refresh',
        cmdArgs: newLocation
    });
  },

  setSigninDestination: function(signinDestination) {
    var self = this;

    switch (signinDestination) {
    case "workspace":
      self.options.signin_destination = signinDestination;
      break;
    }

  },

  setLimebarState: function(state) {
    var limebar_cookie_domain = AXIS._siteData.hosts.limebits.replace("http://www", "").replace(/(:[0-9]*)?\/$/, "");
    if (state == 'reset') {
        AXIS.Cookies.erase("limebar", {
            domain: limebar_cookie_domain,
            path: "/"
        });
    }
    else {
        AXIS.Cookies.create("limebar", state, {
            domain: limebar_cookie_domain,
            path: "/"
        });
    }
  },

  _setupCommandListener: function()
  {
      var self = this;
      if (jQuery.receiveMessage) { // only set up listener if available
          jQuery.receiveMessage(function(e){
              var msg = AXIS.Util.json.safeEval(e.data);
              // pass thru any messages that look like commands 
              if (typeof(msg) == 'object' && msg.cmd) {
                  self.handleCommand(msg);
              } 
          });
      }
  },

  makeJQueryButton: function(obj){
      obj.addClass("ui-button").addClass("ui-button-header").addClass("ui-state-default").addClass("ui-corner-all");
      obj.hover(function(){
          jQuery(this).addClass("ui-state-hover");
      }, function(){
          jQuery(this).removeClass("ui-state-hover");
      });
  }
};

})();
