(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.options = $.extend({
    bit: null,
    showPageTabs: false,
    mode: 'platform',
    bitfinderContextManaged: false,
    messageHandler: function(e) { },
    limebar: this
  }, options);

  this.element.append(
   '<div class="barBody">                                                        \
      <div class="rightCap"></div>                                               \
      <div class="leftCap"></div>                                                \
      <div class="limeLogo"><a></a></div>                                        \
      <div class="bitFinder">                                                    \
        <a class="mybits spacer" title="Show me all my stuff">My Bits</a>        \
        <a class="findbits" title="Find stuff to copy">Find Bits</a>             \
      </div>                                                                     \
      <div class="userNav">                                                      \
        <span class="username spacer inActiveText">NiceTim</span>                \
        <a class="help spacer activeText">Help</a>                               \
        <a class="account spacer activeText" title="Change password or email">Account</a>               \
        <a class="signout activeText">Sign out</a>                               \
        <a class="signin spacer activeText">Sign in</a>                          \
        <a class="join activeText">Join</a>                                      \
      </div>                                                                     \
      <div class="barBackground">                                                \
        <span class="pageNav">                                                   \
          <a class="view activeText" title="Show page"><strong>View</strong></a> \
          <a class="source activeText" title="Show source"><strong>Source</strong></a>                  \
          <a class="configure activeText" title="Customize my Bit"><strong>Configure</strong></a>       \
        </span>                                                                  \
      </div>                                                                     \
    </div>                                                                       \
    <div class="underBar">                                                       \
      <span class="bitName myTag">                                               \
        <a class="bitroot">ScrapBook</a>                                         \
        <br/>                                                                    \
        <a class="owner">ownername</a>                                           \
      </span>                                                                    \
      <span class="bitMarks">                                                    \
        <span class="description">                                               \
          <span class="descriptionText"></span>                                  \
          <br/>                                                                  \
        </span>                                                                  \
        <span class="tags">                                                      \
          <strong>Tags:</strong>                                                 \
          <a>tags</a>                                                            \
        </span>                                                                  \
      </span>                                                                    \
      <span class="bitConfig">                                                   \
        <a class="getbit activeText" title="Copy to My Bits"><strong><span></span>Get Bit!</strong></a> \
        <a class="config activeText" app="mapper"><strong><span></span>Address</strong></a>             \
        <a class="config activeText" app="permissions"><strong><span></span>Sharing</strong></a>        \
        <a class="config activeText" app="flush"><strong><span></span>Content</strong></a>              \
      </span>                                                                    \
      <a class="popout" title="View without toolbar"></a>                        \
    </div>                                                                       \
    <div class="overlay"><div class="nibbler"></div></div>'
  );

  this._setupLogoLink();
  this._setupBitfinderLinks();
  this._setupPagenavLinks();
  this._setupUsernavLinks();
  this._setupBitmarks();
  this._setupBitConfig();
  this._setupGetBit();
  this._setupPopout();
  this._setupOverlay();

  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() {

      self.handleCommand({
        cmd: 'setMode',
        cmdArgs: self.options.mode
      });
    }
  });

  this.handleCommand({
    cmd: 'setLimebarState',
    cmdArgs: 'max'
  });

};

LimeBar.prototype = {

  dropshadowHeight: 8,

  /* TODO: change to function */
  galleryPathPref : '/apps/bitfinder/#tag=All&url=',

  /* TODO: change to function */
  editorPathPref: '/apps/editor/#',

  configAppDescriptions: {
    "mapper": [540, 540, 125],
    "permissions": [650, 260, 125],
    "flush": [540, 264, 125]
  },

  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));
      this.element.trigger('bitChanged');
      break;

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

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

    case "showPageBusy":
      if (o.cmdArgs == "true")
        this.showOverlayOnPage(true);
      else
        this.hideOverlay();
      break;
    }

  },

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

  _setupBitfinderLinks: function() {
    var self = this;

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

    self.element.find('a.findbits').attr('href', self.galleryPathPref + '/');

    this.element.bind('authChanged', function() {
      var user = self.user;
      self.element.find('a.mybits').attr('href', user ? self.galleryPathPref + '/home/' + user :
                                           AXIS._siteData.hosts.secure + 'secure/access.html#sign_up=if_new');
    });

    this.element.bind('authChanged bitChanged', function() {

      if (self.options.bitfinderContextManaged || !self.bit) return;

      self.selectBitfinderLink(self.bit.owner == self.user ? "mybits" : "findbits");

    });

  },

  _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").css('display', 'none');
        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) {
      e.preventDefault();
      AXIS.Login.logout();
      self.options.messageHandler({ cmd: "signedOut" });
    }).attr("href", AXIS._siteData.hosts.limebits);

  },

  _setupPagenavLinks: function() {
    var self = this;

    self.element.find('.pageNav').hide();
    self.element.find('.underBar').hide();

    self.element.find('a.view, a.source').css('display', 'inline-block');

    self.element.bind('authChanged bitChanged', function() {

      if (!self.bit) return;

      self.element.find('a.configure, a.view').attr('href', self.bit.url + '?bar');
      self.element.find('a.source').attr('href', self.editorPathPref + self.bit.tld_path);

      self.element.find('a.configure').css('display', self.bit.owner == self.user ? 'inline-block' : 'none');

    });

    self.element.find('a.view').click(function(e) {
      if (self.options.mode == "view") {
        e.preventDefault();

        if ($(this).hasClass('selected'))
          return;

        self.switchToViewTab();
      }
    });

    this.element.find('a.source').click(function(e) {
      if (self.options.mode == "source") {
        e.preventDefault();

        if ($(this).hasClass('selected'))
          return;

        self.switchToSourceTab();
      }
    });

    this.element.find('a.configure').click(function(e) {
      e.preventDefault();

      if ($(this).hasClass('selected'))
        return;

      self.switchToConfigureTab();
    });

  },

  _setupBitmarks: function() {
    var self = this;

    self.element.find('.tags, .description').hide();
    self.element.find('.bitMarks').removeAttr('loaded');
    self.element.bind('bitChanged', function() {

      self.element.find('.bitName').find('.bitroot').text(self.bit.name).attr('href', self.bit.root_url);

      AXIS.Util.bit.getBitmarks(self.bit.tld_path, function(marks) {

        if (marks['displayname']) self.bit.name = marks['displayname'];
        self.bit.tags = marks['tags'] || [];
        self.bit.description = marks['description'] || null;

        if (self.bit.name)
          {
            var name = self.bit.name;
            if (name.length > self.maxNameLength)
              name = name.slice(0, self.maxNameLength) + "...";
            self.element.find('.bitName .bitroot').text(name);
          }

        if (self.bit.description)
          {
            var desc = self.bit.description;
            if (desc.length > self.maxDescriptionLength)
              desc = desc.slice(0, self.maxDescriptionLength) + "...";
            self.element.find('.descriptionText').text(desc);
          }

        self.element.find('.description').toggle(self.bit.description ? true : false);

        if (self.bit.tags.length) {
          var tag_length = 0;
          self.element.find('.tags a').remove();
          $(self.bit.tags).each(function(i, tag) {
            var last = (self.bit.tags.length - 1 == i);
            tag_length += tag.length + (last ? 0 : 2);
            if (tag_length > self.maxDescriptionLength) 
              {
                self.element.find('.tags a:last-child').text(self.element.find('.tags a:last-child').text().replace(",", "..."));
                return false;
              }
            self.element.find('.tags').append("<a></a>");
            self.element.find('.tags a:last-child').attr('href', '/apps/bitfinder/#url=/&tag=' + tag).text(tag + (last ? "" : ", "));
          });
          self.element.find('.tags').show();
        } else
          self.element.find('.tags').hide();

        self.element.find('.bitMarks').attr('loaded', true);
      });

    });

    self.element.bind('bitChanged authChanged', function() {

      if (!self.bit) return;

      self.bit.owner_href = AXIS._siteData.hosts.limebits.replace("www", self.bit.owner);

      self.element.find('.bitName').removeClass('myTag ownerTag');
      if (self.bit.owner == self.user)
        self.element.find('.bitName').addClass('myTag');
      else
        self.element.find('.bitName').addClass('ownerTag').find('.owner').attr('href', self.bit.owner_href).text(self.bit.owner);
      
    });

  },

  _setupBitConfig: function() {
    var self = this;

    self.element.find('.overlay, a').click(function(e) {
      self.hideAnyDisplayingConfigApp();
    });

    self.element.bind('bitChanged', function() {
      self.element.find('a[app]').attr("href", self.bit.url);
    });

    self.element.find('a[app]').addClass('nibbling');

    self.element.find('a[app]').click(function(e) {
      e.preventDefault();

      if ($(this).hasClass('nibbling'))
        return;

      var name = $(this).attr("app");
      self.showConfigApp(name, e.clientX + " " + e.clientY);
    });

  },

  _setupGetBit: function() {
    var self = this;

    self.element.find('a.getbit').click(function(e) {

      e.preventDefault();

      $(this).addClass('nibbling');
      self.showOverlayOnPage(false);

      AXIS.Util.bit.getBit(self.bit.tld_path);

    });

    self.element.bind('bitChanged', function() {

      self.element.find('a.getbit').attr("href", self.bit.url);

    });

  },

  _setupPopout: function() {
    var self = this;

    self.element.find('a.popout').attr('target', '_blank');
    
    self.element.bind('bitChanged', function() {

      self.element.find('a.popout').attr("href", self.bit.url + '?nobar');

    });

  },

  _setupOverlay: function() {
    var self = this;

    var resize_cb = function() {
      self.element.find('.overlay').css('height', $().height());
      self.element.find('.overlay').css('width', $().width());
    }

    $(window).resize(resize_cb);
  },

  selectBitfinderLink: function(link) {
    var self = this;
    
    self.element.find('.mybits, .findbits').removeClass('selectedText activeText');
    if (link == "mybits")
      self.element.find('.mybits').addClass('selectedText');
    else if (link == "findbits")
      self.element.find('.findbits').addClass('selectedText');

  },

  hidePageTabs: function() {
    var self = this;

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

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

    self.options.mode = mode;
    if (self.options.mode == "platform")
      {
        self.hidePageTabs();
      }
    else if (self.options.mode == 'source')
      {
        self.element.find('.pageNav').show();
        self.switchToSourceTab();
      }
    else if (self.options.mode == 'view')
      {
        self.element.find('.pageNav').show();
        self.switchToViewTab();
      }

    if (self.bit && AXIS.Cookies.read(self.bit.tld_root) == "openConfigure")
      {
        AXIS.Cookies.erase(self.bit.tld_root, {path: "/apps/"});
        if (self.bit.owner == self.user)
          self.switchToConfigureTab();
      }

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

  showSourceTabContent: function() {
    var self = this;

    if (!self.bit) return;

    self.element.addClass('bitBackground');

    self.element.find('.bitConfig a').hide();
    if (self.bit.owner != self.user)
      self.element.find('.bitConfig .getbit').show();
    self.element.find('.underBar').show();

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

  switchToSourceTab: function() {
    var self = this;

    self.element.find('.pageNav a').removeClass('selected');
    self.element.find('a.source').addClass('selected');

    self.showSourceTabContent();
  },

  showViewTabContent: function() {
    var self = this;

    if (!self.bit) return;

    self.element.addClass('bitBackground');

    self.element.find('.bitConfig a').hide();
    if (self.bit.owner != self.user)
      self.element.find('.bitConfig .getbit').show();
    self.element.find('.underBar').show();

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

  switchToViewTab: function() {
    var self = this;

    self.element.find('.pageNav a').removeClass('selected');
    self.element.find('a.view').addClass('selected');

    self.showViewTabContent();
  },

  showConfigureTabContent: function() {
    var self = this;

    self.element.addClass('bitBackground');

    self.element.find('.bitConfig .getbit').hide();
    self.element.find('.bitConfig .config').show();

    self.element.find('.underBar').show();
    self.options.messageHandler({
      cmd: 'refreshHeight'
    });
  },

  switchToConfigureTab: function() {
    var self = this;

    self.element.find('.pageNav a').removeClass('selected');
    self.element.find('a.configure').addClass('selected');

    if (!self.element.find('a.configure').attr('loaded'))
      {
        self.loadConfigurationApps();
        self.element.find('a.configure').attr('loaded', true);
      }
    
    self.showConfigureTabContent();
  },

  loadConfigurationApps: function() {
    var self = this;

    var config_frms = [];
    $.each(self.configAppDescriptions, function(name, desc) {

      var frm = document.createElement('iframe');
      if ($.browser.msie) {
        frm.frameBorder = "0"; // to make IE not show a frame border
        frm.allowTransparency = true; // to make iframe transparent
      }
      self.element.append(frm);
      $(frm).css({ display: 'none'});
      $(frm).attr("app", name);
      config_frms.push(frm);
    });

    var config_wins = $(config_frms).map(function() {
      var frm = this;
      var win = frm.contentWindow || frm.contentDocument.defaultView;
      $(frm).load(function() {
        $(frm).unbind('load', arguments.callee);
        $(frm).attr('loaded', true);

        (function(e, btn_state) {
          if (btn_state === undefined)
            return win.$().bind("btn_state", arguments.callee);

          self.setConfigAppButtonState($(frm).attr("app"), (btn_state ? "enabled" : "disabled"));

          if (e != null)
            win.$().unbind("btn_state", arguments.callee);
        })(null, win.$().attr("btn_state"));

        win.$().bind("close", function(e) {
          self.hideConfigApp($(frm).attr('app'));
        });

        win.$().bind("refresh", function(e, new_url) {
          var newbit = AXIS.Util.bit.bitInfo(new_url);
          AXIS.Cookies.create(newbit.tld_root, "openConfigure", { path: '/apps/' });
          self.refresh(new_url);
        });
        
      })

      win.location.replace(AXIS._siteData.hosts.limebits + 'apps/' + $(this).attr("app") + '/#' +
                           encodeURIComponent(self.bit.tld_root) + '&' + encodeURIComponent(self.bit.url));
    });

  },

  setConfigAppButtonState: function(app, state) {
    var self = this;
    var btn = self.element.find("a[app^='" + app + "']");

    btn.removeClass('nibbling');
    if (state == "enabled")
      btn.addClass('active');
    else
      btn.addClass('inactive');
    
  },

  showConfigApp: function(name, position) {
    var self = this;

    var desc = self.configAppDescriptions[name]
    var height = desc[0];
    var width = desc[1];
    var center_width = desc[2];

    var clientX = position.split(' ')[0];
    var clientY = position.split(' ')[1];

    self.showOverlayUnderBar(null, height);

    var config_frame = self.element.find("iframe[app^='" + name + "']" );
    $(config_frame).css({
      height: height + "px",
      width: width + "px",
      left: clientX - center_width + "px",
      display: 'block'
    });

  },

  hideConfigApp: function(name) {
    var self = this;
    var config_frame = self.element.find("iframe[app^='" + name + "']" );

    $(config_frame).css({ display: "none" });
    self.hideOverlay();
  },

  hideAnyDisplayingConfigApp: function(name) {
    var self = this;
    self.element.find("iframe").each(function() {
      if ($(this).is(':visible'))
        {
          self.hideConfigApp($(this).attr('app'));
          return false;
        }
    });
  },

  showOverlayOnPage: function(nibbler) {
    var self = this;

    self.options.messageHandler({
      cmd: "fullscreen",
      cmdArgs: "on"
    });

    self.element.find(".overlay").css({
      'marginTop': 0,
      'height': $().height()
    }).show();
    self.element.find(".overlay .nibbler").toggle(nibbler);
  },

  showOverlayUnderBar: function(nibbler, minHeight) {
    var self = this;
    nibbler = nibbler ? true : false;
    minHeight = " " + minHeight;
    self.options.messageHandler({
      cmd: "fullscreen",
      cmdArgs: "on" + minHeight
    });

    self.element.find(".overlay").css({
      'marginTop': self.getBarHeight(false),
      'height': $().height()
    }).show();
    self.element.find(".overlay .nibbler").toggle(nibbler);
  },

  hideOverlay: function() {
    var self = this;

    self.options.messageHandler({
      cmd: "fullscreen",
      cmdArgs: "off"
    });

    self.element.find(".overlay").hide();
  },

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

    self.options.messageHandler({
      cmd: "refresh",
      cmdArgs: newLocation
    });
  },

  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;
  },

  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]*)?\/$/, "");
    AXIS.Cookies.create("limebar", state, {
      domain: limebar_cookie_domain,
      path: "/"
    });
  }

};

})();
