/*
 * ***** BEGIN LICENSE BLOCK *****
 * Version: ZAPL 1.1
 * 
 * The contents of this file are subject to the Zimbra AJAX Public
 * License Version 1.1 ("License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.zimbra.com/license
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 * 
 * The Original Code is: Zimbra AJAX Toolkit.
 * 
 * The Initial Developer of the Original Code is Zimbra, Inc.
 * Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK *****
 */

/**
* Creates a menu item. Menu items can be part of a radio group, or can be checked style menu items
*
* @constructor
* @class
*
* @author Ross Dargahi
* @param parent			the parent widget
* @param style 			menu item's style
* @param radioGroupId 	radio group that the menu item is part of
* @param index 			position in menu
* @param className		a CSS class
* @param posStyle		positioning style
*/
function DwtMenuItem(parent, style, radioGroupId, index, className, posStyle) {

	className = className || "DwtMenuItem";
	DwtComposite.call(this, parent, className, posStyle);

	if (!(parent instanceof DwtMenu))
		throw new DwtException("Parent must be a DwtMenu object", DwtException.INVALIDPARENT, "DwtMenuItem");
		
	this._style = style ? style : DwtMenuItem.CASCADE_STYLE;
	if (parent._style == DwtMenu.BAR_STYLE && this._style != DwtMenuItem.PUSH_STYLE)
		throw new DwtException("DwtMenuItemInit: invalid style", DwtException.INVALID_PARAM, "DwtMenuItem"); 

	this._setMouseEventHdlrs();
	this._setKeyEventHdlrs();
	this._origClassName = className;
	this._selectedClassName = className + "-" + DwtCssStyle.SELECTED;
	this._triggeredClassName = className + "-" + DwtCssStyle.TRIGGERED;
	this._iconAreaClassName = className + "-IconArea";
	this._iconAreaSelClassname = this._iconAreaClassName + "-" + DwtCssStyle.SELECTED;
	this._checkedAreaClassName = className + "-CheckedArea";
	this._checkedAreaSelClassname = this._checkedAreaClassName + "-" + DwtCssStyle.SELECTED;
	this._table = this.getDocument().createElement("table");
	this._table.cellSpacing = this._table.cellPadding = 0;
	this._table.border = 0;
	this._table.borderCollapse = "separate";
	this._row = this._table.insertRow(0);

	switch (this._style) {
		case DwtMenuItem.SEPARATOR_STYLE:
			this._createSeparatorStyle();
			break;
		case DwtMenuItem.PUSH_STYLE:
			this._createPushStyle();
			break;
		case DwtMenuItem.RADIO_STYLE:
		case DwtMenuItem.CHECK_STYLE:
			this._createCheckedStyle(radioGroupId);
			break;
	    case DwtMenuItem.SELECT_STYLE:
			this._createSimpleStyle();
			break;
		default:
			this._createCascadeStyle();
	}

	this._mouseOverListener = new AjxListener(this, DwtMenuItem.prototype._mouseOverListener);
	this._mouseOutListener = new AjxListener(this, DwtMenuItem.prototype._mouseOutListener);
	this._mouseUpListener = new AjxListener(this, DwtMenuItem.prototype._mouseUpListener);
	this._mouseDownListener = new AjxListener(this, DwtMenuItem.prototype._mouseDownListener);
	this.addListener(DwtEvent.ONMOUSEOVER, this._mouseOverListener);
	this.addListener(DwtEvent.ONMOUSEOUT, this._mouseOutListener);
	this.addListener(DwtEvent.ONMOUSEUP, this._mouseUpListener);
	this.addListener(DwtEvent.ONMOUSEDOWN, this._mouseDownListener);
	this.getHtmlElement().appendChild(this._table);
	if (parent._addItem)
		parent._addItem(this, index);
	this.setCursor("default");
	this._menu = null;
	this._menuDisposeListener = new AjxListener(this, DwtMenuItem.prototype._menuDisposed)
}

DwtMenuItem.prototype = new DwtComposite;
DwtMenuItem.prototype.constructor = DwtMenuItem;

DwtMenuItem.prototype.toString = 
function() {
	return "DwtMenuItem";
}

DwtMenuItem.CHECKED = 1;
DwtMenuItem.UNCHECKED = 2;

DwtMenuItem.NO_STYLE = 0;
DwtMenuItem.CHECK_STYLE = 1;
DwtMenuItem.RADIO_STYLE = 2;
DwtMenuItem.SEPARATOR_STYLE = 3;
DwtMenuItem.CASCADE_STYLE = 4;
DwtMenuItem.PUSH_STYLE = 5;
DwtMenuItem.SELECT_STYLE = 6;

DwtMenuItem._IMAGECELL_DIM = "22px";
DwtMenuItem._CASCADE_DIM = "16px";
DwtMenuItem._CHECKEDCELL_DIM = "13px";
DwtMenuItem._FILLCELL_DIM = "7px";
DwtMenuItem._MENU_POPUP_DELAY = 250;
DwtMenuItem._MENU_POPDOWN_DELAY = 250

DwtMenuItem.create =
function(parent, imageInfo, text, disImageInfo, enabled, style, radioGroupId, idx, className, posStyle) {
	var mi = new DwtMenuItem(parent, style, radioGroupId, idx, className, posStyle);
	if (imageInfo)
		mi.setImage(imageInfo);
	if (text)
		mi.setText(text);
	if (disImageInfo)
		mi.setDisabledImage(disImageInfo);
	mi.setEnabled(enabled !== false);
	return mi;
}


DwtMenuItem.prototype.addSelectionListener = 
function(listener) {
	this.addListener(DwtEvent.SELECTION, listener);
}

DwtMenuItem.prototype.removeSelectionListener = 
function(listener) {
  this.removeListener(DwtEvent.SELECTION, listener);     	
}

DwtMenuItem.prototype.getChecked =
function() {
	return this._itemChecked;
}

DwtMenuItem.prototype.setChecked =
function(checked, skipNotify) {
	this._setChecked(checked, null, skipNotify);
}

DwtMenuItem.prototype._setChecked =
function(checked, ev, skipNotify) {
	if ((this._style == DwtMenuItem.CHECK_STYLE || this._style == DwtMenuItem.RADIO_STYLE)
		&& this._itemChecked != checked) {
		this._itemChecked = checked;
		
		if (checked) {
			if (this._style == DwtMenuItem.CHECK_STYLE) {
				AjxImg.setImage(this._checkedCell, DwtImg.MENU_CHECK);
			} else {
				AjxImg.setImage(this._checkedCell, DwtImg.MENU_RADIO);
				// This will cause the parent menu to deselect the currently selected radio item
				this.parent._radioItemSelected(this, skipNotify);
			}
			var gp = this.parent.parent ? this.parent.parent : null;
			if (gp && (gp instanceof DwtButton) && (gp._followIconStyle == this._style))
				gp.setImage(this._imageInfo);
		} else {
			AjxImg.setImage(this._checkedCell, DwtImg.BLANK9);
		}
		
		if (skipNotify) return;
		
		// If we are being called as a result of a UI action then ev will not be null and we ahve
		// to initialize our selection event based on the the event.
		var selEv = DwtShell.selectionEvent;
		if (ev)
			DwtUiEvent.copy(selEv, ev);
		else
			selEv.reset();
		selEv.item = this;
		selEv.detail = (checked) ? DwtMenuItem.CHECKED : DwtMenuItem.UNCHECKED;
		this.notifyListeners(DwtEvent.SELECTION, selEv);			
	}
}

DwtMenuItem.prototype.setEnabled =
function(enabled) {
	if (enabled != this._enabled) {
		DwtControl.prototype.setEnabled.call(this, enabled);
		if (enabled) {
			this.addListener(DwtEvent.ONMOUSEOVER, this._mouseOverListener);
			this.addListener(DwtEvent.ONMOUSEOUT, this._mouseOutListener);
			this.addListener(DwtEvent.ONMOUSEUP, this._mouseUpListener);
			this.addListener(DwtEvent.ONMOUSEDOWN, this._mouseDownListener);
			if (this._imageInfo)
				this._setImage(this._imageInfo);
			if (this._textCell)
				this._textCell.className = "Text";
		} else {
			this.removeListener(DwtEvent.ONMOUSEOVER, this._mouseOverListener);
			this.removeListener(DwtEvent.ONMOUSEOUT, this._mouseOutListener);
			this.removeListener(DwtEvent.ONMOUSEUP, this._mouseUpListener);
			this.removeListener(DwtEvent.ONMOUSEDOWN, this._mouseDownListener);
			if (this._disabledImageInfo)
				this._setImage(this._disabledImageInfo);
			if (this._textCell)
				this._textCell.className = "DisabledText";
		}
	}
}


DwtMenuItem.prototype.getDisabledImage =
function() {
	return this._disabledImage;
}

DwtMenuItem.prototype.setDisabledImage =
function(imageInfo) {
	this._disabledImageInfo = imageInfo;
	if (!this._enabled && imageInfo)
		this._setImage(imageInfo);
}

DwtMenuItem.prototype.getImage =
function() {
	return ((this._style == DwtMenuItem.CHECK_STYLE) == 0 && this._imageInfo)
		? this._imageInfo : null;
}

DwtMenuItem.prototype.setImage =
function(imageInfo) {
	this._imageInfo = imageInfo;
	if (this._enabled || (!this._enabled && !this._disabledImageInfo))
		this._setImage(imageInfo);
}

DwtMenuItem.prototype._setImage =
function(imageInfo) {
	if (this._style != DwtMenuItem.SEPARATOR_STYLE) {
		AjxImg.setImage(this._iconCell, imageInfo);
	}
}

DwtMenuItem.prototype.getMenu =
function() {
	return this._menu;
}

DwtMenuItem.prototype.setMenu = 
function(menu) {
	if (this._menu == menu) {
		return;
	} else if (this._menu) {
		this._menu.removeDisposeListener(this._menuDisposeListener);
	}

	this._menu = menu;
	if (menu)
		this._menu.addDisposeListener(this._menuDisposeListener);
	
	if (this._style == DwtMenuItem.CASCADE_STYLE || this._style == DwtMenuItem.CHECK_STYLE
		|| this._style == DwtMenuItem.RADIO_STYLE) {
		if (menu) {
			AjxImg.setImage(this._cascCell, DwtImg.CASCADE);
		} else if (!menu) {
			this._cascCell.innerHTML = "";
		}
	}
}

DwtMenuItem.prototype.setSize = 
function(width, height) {
	DwtComposite.prototype.setSize.call(this, width, height);
	if (width != DwtControl.DEFAULT) {
		width = (typeof(width) == "number") ? width + "px" : width;
		this._table.style.width = width;
	}
	if (height != DwtControl.DEFAULT) {
		height = (typeof(height) == "number") ? height + "px" : height;
		this._table.style.height = height;
	}
}

DwtMenuItem.prototype.getText =
function() {
	if ((this._style == DwtMenuItem.SEPARATOR_STYLE) != 0) return null;
	return this._textCell.innerHTML;
}

DwtMenuItem.prototype.setText =
function(text) {
	if ((this._style == DwtMenuItem.SEPARATOR_STYLE) != 0) return;
	this._textCell.innerHTML = text;
}

DwtMenuItem.prototype._createSeparatorStyle =
function() {
	// TODO - REMOVE MENU_BAR STUFF SINCE MENU BARS CANNOT HAVE SEPARATOR CHILDREN
	this._table.style.width = "100%";
	var i = 0;
	this._iconCell = this._row.insertCell(i++);
	this._iconCell.noWrap = true;
	this._iconCell.align = "center";
	this._iconCell.width = DwtMenuItem._IMAGECELL_DIM;
	this._iconCell.height = "1px"
	this._iconCell.className = this._iconAreaClassName;
	
	var fillCell = this._row.insertCell(i++);
	fillCell.width = DwtMenuItem._FILLCELL_DIM;
	fillCell.noWrap = true;
	
	fillCell = this._row.insertCell(i++);
	fillCell.noWrap = true;
	fillCell.style.width = "100%";
	fillCell.className = this._className + "-Separator";
	fillCell.style.height = "1px";
	
	if (this.parent._menuHasCheckedItems())
		this._checkItemAdded();
}

DwtMenuItem.prototype._createPushStyle =
function() {
	var i = 0;
	this._iconCell = this._row.insertCell(i++);
	this._iconCell.noWrap = true;
	this._iconCell.align = "center";
	this._iconCell.width = this._iconCell.height = DwtMenuItem._IMAGECELL_DIM;
	this._iconCell.className = this._iconAreaClassName;

	var fillCell = this._row.insertCell(i++);
	fillCell.width = DwtMenuItem._FILLCELL_DIM;
	fillCell.noWrap = true;
		
	this._textCell = this._row.insertCell(i++);
	this._textCell.noWrap = true;
	this._textCell.className = this._className + "-Text";
	
	fillCell = this._row.insertCell(i);
	fillCell.width = DwtMenuItem._FILLCELL_DIM;
	fillCell.noWrap = true;	
}

DwtMenuItem.prototype._createSimpleStyle =
function() {
	this._table.style.width = "100%";
	this._textCell = this._row.insertCell(-1);
	this._textCell.noWrap = true;
	this._textCell.className = this._className + "-Text";
	var fillCell = this._row.insertCell(-1);
	fillCell.className = this._className + "-LeftFill";
};

DwtMenuItem.prototype._createCascadeStyle =
function() {
	this._table.style.width = "100%";
	var i = 0;
	this._iconCell = this._row.insertCell(i++);
	this._iconCell.noWrap = true;
	this._iconCell.align = "center";
	this._iconCell.width = this._iconCell.height = DwtMenuItem._IMAGECELL_DIM;
	this._iconCell.className = this._iconAreaClassName;
	
	var fillCell = this._row.insertCell(i++);
	fillCell.width = DwtMenuItem._FILLCELL_DIM;
	fillCell.noWrap = true;
	
	this._textCell = this._row.insertCell(i++);
	this._textCell.noWrap = true;
	this._textCell.className = this._className + "-Text";
	
	this._cascCell = this._row.insertCell(i);
	this._cascCell.noWrap = true;
	this._cascCell.style.width = this._cascCell.style.height = DwtMenuItem._CASCADE_DIM;

	if (this.parent._menuHasCheckedItems())
		this._checkItemAdded();
}

DwtMenuItem.prototype._createCheckedStyle =
function(radioGroupId) {
	this._createCascadeStyle();
	this._checkItemAdded();
	this._radioGroupId = (radioGroupId != null) ? radioGroupId : 0;
	this._itemChecked = false;
}

/* This method is called by DwtMenuItem.prototype._createCheckedStyle when a check or radio style
 * menu item is being created. It is also called by DwtMenu._addItem when a check/radio style item
 * is added to the menu and it allows for the menu item to add a column so that it can align with
 * the new checked item */
DwtMenuItem.prototype._checkItemAdded =
function() {
	if (this._checkedCell == null) {
		this._checkedCell = this._row.insertCell(0);
		this._checkedCell.noWrap = true;
		this._checkedCell.align = "center";
		this._checkedCell.width = DwtMenuItem._CHECKEDCELL_DIM;
		this._checkedCell.height = (this._style != DwtMenuItem.SEPARATOR_STYLE) ?  DwtMenuItem._CHECKEDCELL_DIM : 1;
		this._checkedCell.className = this._checkedAreaClassName;
	}
}

/* This method is explicitly called by DwtMenu._removeChild when the last check/radio item is removed
 * from the menu. It allows for the item to remove its "bogus" check column*/
DwtMenuItem.prototype._checkedItemsRemoved =
function() {
	this._row.deleteCell(0);
}

DwtMenuItem.prototype._menuDisposed =
function(ev) {
	this.setMenu(null);
}

DwtMenuItem.prototype._popdownMenu =
function() {
	//if (this._menu && this._menu.isPoppedup())
		this._deselect(0);
}

DwtMenuItem.prototype._deselect =
function(msec) {
	if (this._style == DwtMenuItem.CASCADE_STYLE || this._style == DwtMenuItem.CHECK_STYLE
		|| this._style == DwtMenuItem.RADIO_STYLE) {
		this._iconCell.className = this._iconAreaClassName;
		if (this._checkedCell)
			this._checkedCell.className = this._checkedAreaClassName;		
		msec = (msec == null) ? DwtMenuItem._MENU_POPDOWN_DELAY : msec;
	}
	if (this._menu)
		this._menu.popdown(msec);
	this.setClassName(this._origClassName);
	this.setCursor("default");
}

DwtMenuItem.prototype._isMenuPoppedup =
function() {
	return (this._menu && this._menu.isPoppedup()) ? true : false;
}

DwtMenuItem.prototype._mouseOverListener = 
function(ev) {
	this.parent.popup();
	if (this._style == DwtMenuItem.SEPARATOR_STYLE)
		return;
	var activeItem = this.parent._getActiveItem();
	this.parent.clearExternallySelectedItems();
	if (this._style == DwtMenuItem.CASCADE_STYLE || this._style == DwtMenuItem.CHECK_STYLE
		|| this._style == DwtMenuItem.RADIO_STYLE) {
		if (activeItem)
			activeItem._deselect();	
		this._iconCell.className = this._iconAreaSelClassName;
		if (this._checkedCell)
			this._checkedCell.className = this._checkedAreaSelClassName;
		if (this._menu)
			this._menu.popup(DwtMenuItem._MENU_POPUP_DELAY);
		this.setSelectedStyle();
	} else if (this._style == DwtMenuItem.PUSH_STYLE || this._style == DwtMenuItem.SELECT_STYLE) {
		if (activeItem)
			activeItem._deselect(0);
		if (activeItem && this._menu) {
			this._menu.popup();
			this.setSelectedStyle();
		} else {
			this.setSelectedStyle()
		}
	}
	ev._stopPropagation = true;
}

DwtMenuItem.prototype.setSelectedStyle = 
function () {
	this.setClassName(this._selectedClassName);
	this._isSelected = true;
};

DwtMenuItem.prototype.setTriggeredStyle = 
function () {
	this.setCursor("wait");
	this.setClassName(this._triggeredClassName);
};

DwtMenuItem.prototype._mouseOutListener = 
function(ev) {
	if (this._style == DwtMenuItem.SEPARATOR_STYLE)
		return;
	if (this._menu == null || !this._menu.isPoppedup())
		this._deselect();
}

DwtMenuItem.prototype._mouseDownListener = 
function(ev) {
	if (ev.button != DwtMouseEvent.LEFT)
		return;
	this.setTriggeredStyle();
}

DwtMenuItem.prototype._mouseUpListener = 
function(ev) {
	if (ev.button != DwtMouseEvent.LEFT)
		return;

	if (this._style == DwtMenuItem.CHECK_STYLE) {
		this._deselect();
		this._setChecked(!this._itemChecked, ev);
		DwtMenu.closeActiveMenu();
	} else if (this._style == DwtMenuItem.RADIO_STYLE) {
		if (!this._itemChecked) {
			this._setChecked(!this._itemChecked, ev);
			if (this._menu) {
				this._menu.popup(0);
			} else {
				DwtMenu.closeActiveMenu();
			}
		} else if (this._menu){
			this._menu.popup(0);
		} else {
			DwtMenu.closeActiveMenu();
			// at the very least, notify menu item was clicked again
			var selEv = DwtShell.selectionEvent;
			if (ev)
				DwtUiEvent.copy(selEv, ev);
			else
				selEv.reset();
			selEv.item = this;
			selEv.detail = (this._itemChecked) ? DwtMenuItem.CHECKED : DwtMenuItem.UNCHECKED;
			this.notifyListeners(DwtEvent.SELECTION, selEv);			
		}
	} else if (this._style != DwtMenuItem.PUSH_STYLE) {
		if (this._menu) {
			// We know we have a menu to popup
			this._menu.popup(0);
		} else if (this.isListenerRegistered(DwtEvent.SELECTION)) {
			this._deselect();
			var selEv = DwtShell.selectionEvent;
			DwtUiEvent.copy(selEv, ev);
			selEv.item = selEv.dwtObj;
			selEv.detail = 0;
			this.notifyListeners(DwtEvent.SELECTION, selEv);
			DwtMenu.closeActiveMenu();
		}  else {
			this._deselect();
			DwtMenu.closeActiveMenu();
		}
	} else if (this._style == DwtMenuItem.PUSH_STYLE){
		if (this._menu){
			if (!this._isMenuPoppedup()){
				this._menu.popup(0);
			} else {
				this._deselect(0);
			}
		}
	}
	return true;
}

