// class Widget extends WebObject
function Widget()
{
	this.domContainer		= this.createDOMContainer();
	this.onSizeChanged		= new EventDelegate();
	this.onLocationChanged	= new EventDelegate();
	this.updateSuspended	= false;
	
	this.initialize();
}

Widget.prototype = new WebObject;

// protected Element<?> createDOMContainer()
Widget.prototype.createDOMContainer = function Widget_createDOMContainer()
{
	return document.createElement("div");
};

// public Element<?> getDOMContainer()
Widget.prototype.getDOMContainer = function Widget_getDOMContainer()
{
	return this.domContainer;
};

// public void setOpacity(double opacity);
Widget.prototype.setOpacity = function(value)
{
	if(!isNumber(value))
	{
		raise("Invalid opacity " + value);
	} else
	{
		with(this.domContainer.style)
		{
			opacity = value; 
			MozOpacity = value; 
			KhtmlOpacity = value; 
			filter = "alpha(opacity=" + (value * 100) + ")";
		}
		
		this._opacity = opacity;
	}
};

// public double getOpacity();
Widget.prototype.getOpacity = function()
{
	return ("_opacity" in this ? this._opacity : 1);
};

// protected void initialize();
Widget.prototype.initialize = function Widget_initialize()
{
	var theme	= Theme.getCurrentTheme();
	var skin	= null;
	
	with(this.domContainer.style)
	{
		position	= "absolute";
		left		= 0;
		top			= 0;
		// width       = 0;
		// height      = 0;
		
		if(Toolkit.getBrowser() == Toolkit.INTERNET_EXPLORER)
		{
			try
			{
				clip = "rect(0 100% 100% 0)";
			} catch (e)
			{
			}
		}
	}
	
	this.updateTheme = getMethodPointer(this, function(theme) {
		// Do this when the widget is displayed instead!
		this.setSkin(theme.getSkin(this.getWidgetName()));
	});
	
	if(theme)
	{
		this.updateTheme(theme);
	}
	
	// This should work, but it doesn't...
	// Theme.onThemeChanged.addEventListener(this.updateTheme);
};

// public void dipose();
Widget.prototype.dispose = function Widget_dispose()
{
	Theme.onThemeChanged.removeEventListener(this.updateTheme);
	
	this.domContainer.removeNode();
	this.onSizeChanged.dispose();
	this.onLocationChanged.dispose();
	
	delete this.domContainer;
	delete this.onSizeChanged;
	delete this.onLocationChanged;
};

// public { width:int, height:int } getPreferredSize();
Widget.prototype.getPreferredSize = function Widget_getPreferredSize()
{
	if(this.preferredSize)
	{
		return {width:this.preferredSize.width, height:this.preferredSize.height};
	} else
	{
		return (this.preferredSize = { width:this.domContainer.clientWidth, height:this.domContainer.clientHeight });
	}
};

// public void setPreferredSize({width:int, height:int});
Widget.prototype.setPreferredSize = function Widget_setPreferredSize(size)
{
	this.preferredSize = size;
	
	if(this.update && !this.updateSuspended)
	{
		this.update();
	}
};

// public { width:int, height:int } getSize();
Widget.prototype.getSize = function Widget_getSize()
{
	return {width: this.getWidth(), height: this.getHeight()};
};

// public int getWidth();
Widget.prototype.getWidth = function Widget_getWidth()
{
	with(this.domContainer)
	{
		if(style.width == Toolkit.EMPTY_STRING)
		{
			w = clientWidth;
		} else
		{
			w = parseInt(style.width);
		}
	}
	
	return (isNaN(w) ? 0 : w);
};

// public int getHeight();
Widget.prototype.getHeight = function Widget_getHeight()
{
	var h = 0;
	
	with(this.domContainer)
	{
		if(style.height == Toolkit.EMPTY_STRING)
		{
			h = clientHeight;
		} else
		{
			h = parseInt(style.height);
		}
	}
	
	return (isNaN(h) ? 0 : h)
};

// public void setSize(w:int, h:int);
Widget.prototype.setSize = function Widget_setSize(w, h)
{
	if(!isNumber(w) || !isNumber(h))
	{
		raise("Parameter 'w' and 'h' must be numeric");
	} else
	{
		var oldSize = { width:parseInt(this.domContainer.style.width), height:parseInt(this.domContainer.style.height) };
		
		with(this.domContainer.style)
		{
			try
			{
				width 	= parseInt(w);
				height	= parseInt(h);
				clip	= "rect(0 " + w + " " + h + " 0)";
			} catch (e)
			{
				raise(e.description);
			}
		}
		
		if(this.update && !this.updateSuspended)
		{
			this.update();
		}
		
		this.onSizeChanged.fireEvent(this, oldSize, { width: w, height: h });
	}
};

// public int getX();
Widget.prototype.getX = function Widget_getX()
{
    return (parseInt(this.domContainer.style.left));
};

// public int getY();
Widget.prototype.getY = function Widget_getY()
{
    return (parseInt(this.domContainer.style.top));
};

// public void setLocation(int x, int y);
Widget.prototype.setLocation = function Widget_setLocation(nx, ny)
{
	var oldLocation = this.getLocation();
	
	with(this.domContainer.style)
	{
		try
		{
			left = nx;
			top	= ny;
		} catch (e)
		{
			raise("Invalid coordinate (" + nx + ", " + ny + ")");
		}
	}
	
	this.onLocationChanged.fireEvent(this, oldLocation, { x: nx, y: ny });
};

// public { x:int, y:int } getLocation();
Widget.prototype.getLocation = function Widget_getLocation()
{
	with(this.domContainer.style)
	{
		return { x: parseInt(left), y: parseInt(top) };
	}
};

Widget.prototype.setBounds = function Widget_setBounds(x, y, width, height)
{
	this.setLocation(x, y);
	this.setSize(width, height);
};

// public void setSkin(Skin skin);
Widget.prototype.setSkin = function Widget_setSkin(skin)
{
	if(skin != this.skin)
	{	
		if(this.skin)
		{
			this.skin.uninstall(this);
			delete this.skin;
		}
		
		if(skin)
		{
			this.skin = skin;
			this.skin.install(this);
		}
	}
};

// public Skin getSkin();
Widget.prototype.getSkin = function Widget_getSkin()
{
	return this.skin;
};

// public Container getContainer();
Widget.prototype.getContainer = function Widget_getContainer()
{
	return this.container;
};

// public String getSkinName();
Widget.prototype.getWidgetName = function Widget_getWidgetName()
{
	return null;
};

// public void setUpdateSuspended(boolean suspended);
Widget.prototype.setUpdateSuspended = function Widget_setUpdateSuspended(suspended)
{
	this.updateSuspended = suspended;
};

// public boolean isUpdateSuspended();
Widget.prototype.isUpdateSuspended = function Widget_isUpdateSuspended()
{
	return this.updateSuspended;
};

// public void setPadding({top:int, right:int, bottom:int, left:int});
Widget.prototype.setPadding = function Widget_setPadding(padding)
{
	this.padding = padding;
};

// public {top:int, right:int, bottom:int, left:int} getPadding();
Widget.prototype.getPadding = function Widget_getPadding()
{
	if(this.padding)
	{
		return this.padding;
	} else
	{
		return {top:0, right:0, bottom:0, left:0};
	}
};

// public Desktop getDesktop();
Widget.prototype.getDesktop = function Widget_getDesktop()
{
	var parent = this.container;
	
	while(parent && parent.container)
	{
		if(parent.container)
		{
			parent = parent.container;
		} else
		{
			break;
		}
	}
	
	return parent;
};

// public void setVisible(boolean visible);
Widget.prototype.setVisible = function Widget_setVisible(visible)
{
    this.domContainer.style.visibility = (visible ? "visible" : "hidden");
};

// public boolean isVisible();
Widget.prototype.isVisible = function Widget_isVisible()
{
    return (this.domContainer.style.visibility == "visible");
};

Widget.prototype.setMinimumSize = function Widget_setMinimumSize(minimumSize)
{
	if(!minimumSize || !("width" in minimumSize) || !("height" in minimumSize))
	{
		throw new Error("Illegal argument - expected minimumSize = {width:int, height:int}");
	} else
	{
		this.minimumSize = minimumSize;
	}
}

Widget.prototype.getMinimumSize = function Widget_getMinimumSize()
{
	return this.minimumSize;
}

Widget.prototype.invokeUpdate = function Widget_invokeUpdate()
{
	if(this.update && this.container && !this.updateSuspended)
	{
		var thisRef = this;
		
		if(this._pendingUpdateID)
		{
			window.clearTimeout(this._pendingUpdateID);
		}
		
		window.setTimeout(function() {
			thisRef.update();
			delete thisRef.pendingUpdateID;
		}, 100);
	}
}

Widget.prototype.toString = function Widget_toString()
{
	return "Widget [name = " + this.getWidgetName() + ", bounds = {" + this.getX() + ", " + this.getY() + ", " + this.getWidth() + ", " + this.getHeight() + "}]";
}
