var UserMenuItem = klass.create();
Object.extend(UserMenuItem.prototype, {
  initialize: function(parent, container, text, callback) {
    this.parent = parent;
    this.container = container;
    this.text = text;
    this.callback = callback;
    this.initializeComponents();
    Event.observe(this.cell, 'mouseover',
                  this.mouseOver.bindAsEventListener(this));
    Event.observe(this.cell, 'mouseout',
                  this.mouseOut.bindAsEventListener(this));
    Event.observe(this.cell, 'click',
                  this.mouseClick.bindAsEventListener(this));
  },

  initializeComponents: function() {
    var row = $E('tr');
    this.container.appendChild(row);
    this.cell = $E('td');
    row.appendChild(this.cell);
    this.cell.appendChild($T(this.text));
    this.cell.className = 'item';
    // this.cell.style.fontSize = '8pt';
    // this.cell.style.backgroundColor = '#ccc';
    // this.cell.style.cursor = 'pointer';
    // this.cell.style.margin = '2px';
  },
  
  mouseClick: function() {
    this.callback();
  },

  mouseOver: function() {
    // this.cell.style.backgroundColor = 'yellow';
    this.cell.className = 'selected';
  },

  mouseOut: function() {
    // this.cell.style.backgroundColor = '#ccc';
    this.cell.className = 'item';
  }
});

var UserMenu = klass.create();
Object.extend(UserMenu.prototype, {
  initialize: function(container, userId, username, state) {
    this.userId = userId;
    this.username = username;
    this.container = container;
    this.menuContainer = null;
    this.state = state;

    this.initializeComponents();
    this.bindEvents();
    Global.registerContextMenu(this);
  },

  destroy: function() {
    document.body.removeChild(this.menuContainer);
    this.menuContainer = null;
    // Event.stopObserving(document.body, 'click', this.documentClickCallback);
  },

  bindEvents: function() {
    // this.documentClickCallback = this.cancel.bindAsEventListener(this);
    // Event.observe(document.body, 'click', this.documentClickCallback);
  },

  initializeComponents: function() {
    this.menuContainer = $E('div');
    this.menuContainer.className = 'userMenu';
    this.menuContainer.style.top = '0px';
    this.menuContainer.style.left = '0px';
    this.menuContainer.style.position = 'absolute';
    this.menuContainer.style.visible = 'hidden';
    this.menuContainer.style.display = 'none';
    var table = $E('table');
    this.menuContainer.appendChild(table);
    var body = $E('tbody');
    table.appendChild(body);

    new UserMenuItem(this, body, 'send message',
                     this.sendMessage.bind(this));
    if (this.state == 'subscribed') {
      new UserMenuItem(this, body, 'unsubscribe',
                       this.unsubscribeUser.bind(this));
      new UserMenuItem(this, body, 'block',
                       this.blockUser.bind(this));
    } else if (this.state == 'blocked') {
      new UserMenuItem(this, body, 'subscribe',
                       this.subscribeUser.bind(this));
      new UserMenuItem(this, body, 'unblock',
                       this.unblockUser.bind(this));
    } else {
      new UserMenuItem(this, body, 'subscribe to user',
                       this.subscribeUser.bind(this));
      new UserMenuItem(this, body, 'block',
                       this.blockUser.bind(this));
    }

    document.body.appendChild(this.menuContainer);
    var position = this.calculatePlacement();
    this.positionAndShow(position.x, position.y);
  },

  positionAndShow: function(x, y) {
    this.menuContainer.style.top = y + 'px';
    this.menuContainer.style.left = x + 'px';
    this.menuContainer.style.display = 'block';
    this.menuContainer.style.visible = 'visible';
  },

  calculatePlacement: function() {
    var offset = Element.cumulativeOffset(this.container);
    var offsetX = offset[0];
    var offsetY = offset[1];
    var parentHeight = Element.getHeight(this.container);
    var dimensions = document.viewport.getDimensions();
    var width = Element.getWidth(this.menuContainer);
    var height = Element.getHeight(this.menuContainer);

    var positionY = parentHeight + offsetY;
    var positionX = offsetX;

    // FIXME - IE 6 does not return viewport correctly
    //         why isn't this in the documentation?
    if ((dimensions.width == 0) && (dimensions.height == 0)) {
      return {'x': positionX, 'y': positionY};
    }

    // FIXME - research this
    // alert(dimensions.height + ':' + (height + positionY));
    // if ((height + positionY) > dimensions.height) {
    //   positionY = dimensions.height - height;
    // }

    // if ((width + offsetX) > dimensions.width) {
    //   positionX = dimensions.width - width;
    // }
    // alert(positionX + ', ' + positionY);

    return {'x': positionX, 'y': positionY};
  },

  callResult: function(req, json, extra) {
    if (req.status != 200) return;
    var response = xrpcBind(req.responseXML);
    if (!response.ok) {
      // TODO - proper message on error
      alert('Could perform action');
    }
    window.location = window.location;
  },

  subscribeUser: function() {
    Global.call(this.callResult.bind(this),
                'userSubscribe', this.userId);
  },

  unsubscribeUser: function() {
    Global.call(this.callResult.bind(this),
                'userUnsubscribe', this.userId);
  },

  blockUser: function() {
    Global.call(this.callResult.bind(this),
                'userBlock', this.userId);
  },

  unblockUser: function() {
    Global.call(this.callResult.bind(this),
                'userUnblock', this.userId);
  },

  sendMessage: function() {
    userMessagePopup(this.username);
  },

  cancel: function(evt) {
    this.destroy();
  }
});

function userMenuInvoke(container, userId, username, state, evt) {
  new UserMenu(container, userId, username, state);
  Event.stop(evt);
  return false;
}
// vim: set sts=2 sw=2 expandtab:

