/**
 *	In XHTML while specifing widht/height , the unit must be specified e.g. 13px and not 13 alone
 */
if( isIE == null ) var isIE = ( navigator.appName == "Microsoft Internet Explorer" );
Array.prototype.insert = function( item , index ) {
	for( var i = this.length - 1 ; i >= index ; i-- ) this[i+1] = this[i];
	this[index] = item;
}
Array.prototype.remove = function( index ) {
	for( var i = index ; i < this.length-1 ; i++ ) this[i] = this[i+1];
	this.pop();
}
//TODO	creating Menu should be connected with appending it to its parent and setting className, loading afterwards
function MenuPort( type )	{
	this.items = [];
	this.attributes = [];
	if( isIE ) this.node = document.createElement( "<TABLE CELLSPACING=0>" );
	else this.node = document.createElement( "TABLE" );
	this.node.appendChild( document.createElement( "TBODY" ) );
	this.node.appendChild( document.createElement( "CAPTION" ) );
	this.titleNode = this.node.childNodes[1];

	this.node.style.display = "none";
	this.node.parent = this;	//to give access to this object from its HTMLNode representative
	this.setType( type );
	this.id = (new Date()).getTime();
}
MenuPort.prototype.id = null;
MenuPort.prototype.name = null;
MenuPort.prototype.node = null;
MenuPort.prototype.mountPoint = null;
MenuPort.prototype.attributes = [];
MenuPort.prototype.items = [];
MenuPort.prototype.selectedIndex = -1;
MenuPort.prototype.parent = null;
MenuPort.prototype.visible = null;
MenuPort.prototype.className = null
MenuPort.prototype.onnewitem = null;
MenuPort.prototype.selectedItem = null;
MenuPort.prototype.type = "";

MenuPort.prototype.isVisible = function() {
	return this.node.style.display == "";
}

MenuPort.prototype.getClassName = function() {
	return this.attributes["className"];
}
MenuPort.prototype.setClassName = function(v) {
	this.attributes["className"] = v;
	this.node.className = v;
	for( var i = 0 ; i < this.items.length; i++ ) {
		if( this.items[i].getRole() == "submenu" ) this.items[i].getSubmenu().setClassName( v );
		this.items[i].setClassName( this.getClassName() + "Item" );
	}
}

MenuPort.prototype.getSelectedIndex = function() {
	return this.attributes["selectedIndex"];
}
MenuPort.prototype.setSelectedIndex = function(v) {
	if( v >= this.items.length || v < 0 ) v = -1;
	this.attributes["selectedIndex"] = v;
	if( this.getSelectedIndex() > -1 ) {
		this.selectedItem = this.items[ this.getSelectedIndex() ];
	}else this.selectedItem = null;
	this.focusSelected();
}

MenuPort.prototype.getType = function() {
	return this.attributes["type"];
}
MenuPort.prototype.setType = function(v) {
	if( v != "vertical" && v != "horizontal" ) v = "vertical";
	this.attributes["type"] = v;
	this.node.firstChild.className = v;
	if( this.mountPoint ) while( this.mountPoint.childNodes.length > 0 ) this.mountPoint.removeChild( this.mountPoint.firstChild );
	if( v == "vertical" ) {
		this.mountPoint = this.node.firstChild;
	} else {
		this.node.firstChild.appendChild( document.createElement( "TR" ) );
		this.mountPoint = this.node.firstChild.firstChild;
	}
	if( this.items.length > 0 && this.items[0].type != v ) {
		/*	changing menu items	*/
		for( var i = 0 ; i < this.items.length ; i++ ) {
			this.items[i].setType( v );
			this.mountPoint.appendChild( this.items[i].node );
		}
	}
}

MenuPort.prototype.setParent = function(v) {
	this.attributes["parent"] = v;
	this.node.style.position = ( v ) ? "absolute" : "static";
	/**
	 *	if menu is a submenu it may not have margins set to auto, cause Firefox messes positioning
	 */
	if( v ) {
		this.node.style.marginLeft = 0;
		this.node.style.marginRight = 0;
	}
}
MenuPort.prototype.getParent = function() {
	return this.attributes["parent"];
}



MenuPort.prototype.load = function(o) {
	if( ! o ) return;
	this.id = o.id;
	this.name = o.name;
	this.titleNode.innerHTML = o.name;
	this.setClassName( o.className );
	for( var i = 0 ; i < o.items.length ; i++ ) {
		if( o.items[i] ) this.newItem( o.items[i] );
	}
	this.setSelectedIndex(-1);
}
MenuPort.prototype.newItem = function( menuItemDescription ) {
	if( ! this.getType() ) return alert( "No type specified" );
	if( this.getSelectedIndex() >=0 && this.getSelectedIndex() < this.items.length - 1 ) {
		this.items.insert( new MenuItemPort( this , menuItemDescription ) , this.getSelectedIndex() + 1 );
		this.setSelectedIndex( this.getSelectedIndex() + 1 );
		this.mountPoint.insertBefore( this.selectedItem.node , this.mountPoint.childNodes[ this.getSelectedIndex() ] );
	}else {
		this.items.push( new MenuItemPort( this , menuItemDescription ) );
		this.select( this.items[ this.items.length - 1 ] );
		this.mountPoint.appendChild( this.selectedItem.node );
	}
	if( this.onnewitem ) this.onnewitem();
	return this.selectedItem;
}
MenuPort.prototype.removeItem = function( item ) {
	if( item ) this.setSelectedIndex( item.getIndex() );
	if( ! this.selectedItem ) return;
	if( this.items.length == 1 ) return alert( "Nie można usunąć jedynej pozycji w menu" );
	if( this.selectedItem.getSubmenu() ) this.selectedItem.getSubmenu().remove();
	this.mountPoint.removeChild( this.selectedItem.node );
	this.items.remove( this.getSelectedIndex() );
	if( this.getSelectedIndex() >= this.items.length ) this.setSelectedIndex( this.getSelectedIndex() - 1 );
	this.select( this.items[ this.getSelectedIndex() ] );
	if( this.onremoveitem ) this.onremoveitem();
	return this.selectedItem;
}
MenuPort.prototype.focusSelected = function() {
	for( var i = 0 ; i < this.items.length ; i++ ) if( i != this.getSelectedIndex() )
		this.items[i].blur();
	if( this.selectedItem ) this.selectedItem.focus();
}
MenuPort.prototype.select = function ( item ) {
	for( var i = 0 ; i < this.items.length ; i++ ) if( this.items[i] == item ) {
		this.setSelectedIndex( i );
		return;
	}
	this.setSelectedIndex(-1);
}


MenuPort.prototype.remove = function() {
	for( var i = 0 ; i < this.items.length ; i++ )
		this.items[i].removeSubmenu();
	this.node.parentNode.removeChild( this.node );	
}
MenuPort.prototype.hide = function() {
	for( var i = 0 ; i < this.items.length ; i++ )
		this.items[i].blur();
	this.node.style.display = "none";
}
MenuPort.prototype.show = function() {
	this.node.style.display = "";
	if( this.getParent() && this.getParent().parent.isVisible() ) {
		for( var i = 0 ; i < this.items.length ; i++ )
			this.items[i].blur();
		var top = this.getParent().getOffsetTop() + ( ( this.getParent().getType() == "vertical" ) ? 0 : this.getParent().getOffsetHeight() );
		var left = this.getParent().getOffsetLeft() + ( ( this.getParent().getType() == "vertical" ) ? this.getParent().getOffsetWidth() : 0 );
	/*
		alert(this.getParent().getOffsetLeft() + " "+this.getParent().getOffsetWidth()+"\n"+
		this.node.offsetWidth +"+"+ left +" ("+(this.node.offsetWidth + left)+") > "+document.body.offsetWidth );	
	*/
		var menuOffsetWidth = ( this.items.length > 0 ) ? parseInt(this.items[0].node.offsetWidth) : parseInt(this.node.offsetWdith);
		if( menuOffsetWidth + left > document.body.offsetWidth )
			left = parseInt( this.getParent().getOffsetLeft() ) - menuOffsetWidth;
		var windowInnerHeight = ( isIE ) ? document.documentElement.clientHeight : window.innerHeight;

		if( this.node.offsetHeight + top > windowInnerHeight )
			top = windowInnerHeight - this.node.offsetHeight;

		this.node.style.top = top+"px";
		this.node.style.left = left+"px";
	}
}
MenuPort.prototype.shiftItem = function( direction ) {
	if( ! this.selectedItem ) return false;
	if( direction > 0 && this.getSelectedIndex() < this.items.length - 1 ) {
		this.items.push( this.selectedItem );
		this.items[ this.getSelectedIndex() ] = this.items[ this.getSelectedIndex() + 1 ];
		this.items[ this.getSelectedIndex() + 1 ] = this.items[ this.items.length - 1 ];
		this.items.pop();
		if( this.getSelectedIndex() + 1 == this.items.length ) {
			this.mountPoint.removeChild( this.selectedItem.node );
			this.mountPoint.appendChild( this.selectedItem.node );
		} else
			this.mountPoint.insertBefore( this.selectedItem.node , this.mountPoint.childNodes[ this.getSelectedIndex() + 2 ] );
	}else if( direction < 0 && this.getSelectedIndex() > 0 ) {
		this.items.push( this.selectedItem );
		this.items[ this.getSelectedIndex() ] = this.items[ this.getSelectedIndex() - 1 ];
		this.items[ this.getSelectedIndex() - 1 ] = this.items[ this.items.length - 1 ];
		this.items.pop();
		this.mountPoint.insertBefore( this.selectedItem.node , this.mountPoint.childNodes[ this.getSelectedIndex() - 1 ] );
	}

	this.select( this.selectedItem );
	return true;
}
