/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.widgets;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.events.*;

public class Button extends Control {
	String text = "";
	Image image;
	static final boolean COMMAND_LINK = false;

public Button (Composite parent, int style) {
	super (parent, checkStyle (style));
}

public void addSelectionListener (SelectionListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	TypedListener typedListener = new TypedListener (listener);
	addListener (SWT.Selection,typedListener);
	addListener (SWT.DefaultSelection,typedListener);
}

static int checkStyle (int style) {
	style = checkBits (style, SWT.PUSH, SWT.ARROW, SWT.CHECK, SWT.RADIO, SWT.TOGGLE, COMMAND_LINK ? SWT.COMMAND : 0);
	if ((style & (SWT.PUSH | SWT.TOGGLE)) != 0) {
		return checkBits (style, SWT.CENTER, SWT.LEFT, SWT.RIGHT, 0, 0, 0);
	}
	if ((style & (SWT.CHECK | SWT.RADIO)) != 0) {
		return checkBits (style, SWT.LEFT, SWT.RIGHT, SWT.CENTER, 0, 0, 0);
	}
	if ((style & SWT.ARROW) != 0) {
		style |= SWT.NO_FOCUS;
		return checkBits (style, SWT.UP, SWT.DOWN, SWT.LEFT, SWT.RIGHT, 0, 0);
	}
	return style;
}

public int getAlignment () {
	checkWidget ();
	if ((style & SWT.ARROW) != 0) {
		if ((style & SWT.UP) != 0) return SWT.UP;
		if ((style & SWT.DOWN) != 0) return SWT.DOWN;
		if ((style & SWT.LEFT) != 0) return SWT.LEFT;
		if ((style & SWT.RIGHT) != 0) return SWT.RIGHT;
		return SWT.UP;
	}
	if ((style & SWT.LEFT) != 0) return SWT.LEFT;
	if ((style & SWT.CENTER) != 0) return SWT.CENTER;
	if ((style & SWT.RIGHT) != 0) return SWT.RIGHT;
	return SWT.LEFT;
}

String getNameText() {
	return getText ();
}

public Image getImage () {
	checkWidget ();
	return image;
}

public boolean getSelection () {
	checkWidget ();
	if ((style & (SWT.CHECK | SWT.RADIO | SWT.TOGGLE)) == 0) return false;
	return _getSelection ();
}

public String getText () {
	checkWidget ();
	if ((style & SWT.ARROW) != 0) return "";
	return text;
}

void hookEvents () {
	super.hookEvents();
	_hookEvents("onclick",	SWT.Selection);
}

void releaseWidget () {
	super.releaseWidget ();
	text = null;
	image = null;
}

public void removeSelectionListener (SelectionListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (eventTable == null) return;
	eventTable.unhook (SWT.Selection, listener);
	eventTable.unhook (SWT.DefaultSelection,listener);	
}

//TODO implement that the action is commanded by the Java side code.
void sendSelection () {	
//	if ((style & (SWT.CHECK | SWT.TOGGLE)) != 0) {
//		setSelection (!getSelection ());
//	} else {
//		if ((style & SWT.RADIO) != 0) {
//			if ((parent.getStyle () & SWT.NO_RADIO_GROUP) != 0) {
//				setSelection (!getSelection ());
//			} else {
//				selectRadio ();
//			}
//		}
//	}
	postEvent (SWT.Selection);
}

public void setAlignment (int alignment) {
	checkWidget ();
	if ((style & SWT.ARROW) != 0) {
		if ((style & (SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT)) == 0) return; 
		style &= ~(SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT);
		style |= alignment & (SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT);
	} else {
		if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) return;
		style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER);
		style |= alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER);
	}
	_setAlignment (alignment);
}

public void setImage (Image image) {
	checkWidget ();
//TODO not throw exception
//	if (image != null && image.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
	if ((style & SWT.ARROW) != 0) return;
	this.image = image;
	_setImage (image.imagePath);
}

public void setSelection (boolean selected) {
	checkWidget ();
	if ((style & (SWT.CHECK | SWT.RADIO | SWT.TOGGLE)) == 0) return;
	_setSelection (selected);
}

public void setText (String string) {
	checkWidget ();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	if ((style & SWT.ARROW) != 0) return;
	text = string;
	_setText (string);
}

/*---------------------- NATIVE INTERFACE -------------------*/

protected native void _createHandle (Widget parent, int style, int index) /*-{
	if((style & (@org.eclipse.swt.SWT::ARROW)) != 0) {
		if(!$wnd.dojo._hasResource["org.eclipse.swt.ArrowButton"]){
			$wnd.dojo._hasResource["org.eclipse.swt.ArrowButton"] = true;
			$wnd.dojo.provide("org.eclipse.swt.ArrowButton");
			
			$wnd.dojo.require("dijit.form.Button");
		
			$wnd.dojo.declare("org.eclipse.swt.ArrowButton", $wnd.dijit.form.Button, {
				border: "",
				label: "&#9650;",
				staticClass: "swtControl",
				wrap: "",
				getNativeBounds: function(){
					var dnLoc = $wnd.swt.getNativeLocation(this.domNode);
					var fontSize = $wnd.dojo.style(this.containerNode,"fontSize");
					$wnd.swt.setCssStyle(this.containerNode, {fontSize: "large"});
					var fnSize = $wnd.swt.getNativeSize(this.focusNode);
					$wnd.swt.setCssStyle(this.containerNode, {fontSize: fontSize});
					var dnMarginExtends = $wnd.dojo._getMarginExtents(this.domNode);
					var dnPadBorderExtends = $wnd.dojo._getPadBorderExtents(this.domNode);
					return {
						l: dnLoc.l, 
						t: dnLoc.t,
						w: fnSize.w + dnMarginExtends.w + dnPadBorderExtends.w,
						h: fnSize.h + dnMarginExtends.h + dnPadBorderExtends.h
					};
				},
				postCreate: function(){
					this.inherited("postCreate",arguments); 
					$wnd.swt.setCssStyle(this.domNode, {border: this.border});
					$wnd.swt.setCssStyle(this.focusNode, {padding: "0px"});
					this.containerNode.innerHTML = this.label;
				},
				resize: function(){},
				setAlignment: function(alignment){
					switch(alignment){
						case "left":
						  this.containerNode.innerHTML = this.label = "&#9668;"; break;
						case "right":
						  this.containerNode.innerHTML = this.label = "&#9658;"; break;
					    case "up":
						  this.containerNode.innerHTML = this.label = "&#9650;"; break;
					  	case "down":
						  this.containerNode.innerHTML = this.label = "&#9660;"; break;
					}
				},
				setImage: function(image){
					this.iconNode.innerHTML = "<img src='"+image+"'/>";
				},
				setLabel: function(content){},
				setWidgetBounds: function(dim){
					$wnd.swt.setBounds(this.domNode, dim);
					$wnd.swt.setBounds(this.focusNode, dim);
					$wnd.swt.setCssStyle(this.containerNode, {fontSize: Math.max(Math.min(dim.w,dim.h),1)*0.5})
				}
			});
		}
	}
	if((style & (@org.eclipse.swt.SWT::CHECK)) != 0) {
		if(!$wnd.dojo._hasResource["org.eclipse.swt.CheckBox"]){
			$wnd.dojo._hasResource["org.eclipse.swt.CheckBox"] = true;
			$wnd.dojo.provide("org.eclipse.swt.CheckBox");
			
			$wnd.dojo.require("dijit.form.CheckBox");
		
			$wnd.dojo.declare("org.eclipse.swt.CheckBox", $wnd.dijit.form.CheckBox, {
				border: "",
				label: "",
				templateString:
					'<div class="dijitContainer" dojoAttachPoint="focusNode" dojoAttachEvent="onmouseover:_onMouse,onmouseout:_onMouse,onclick:_onClick"/>' +
						'<table dojoAttachPoint="containerNode" border="0" cellpadding="0" cellspacing="0"><tr>' +
							'<td>' +
							 	'<div dojoAttachPoint="stateNode" waiRole="presentation">' +
									'<input type="${type}" class="dijitReset dijitCheckBoxInput" dojoAttachPoint="inputNode">' +
								'</div>' + 
							'</td>' +
							'<td dojoAttachPoint="alignNode" >' +
								'<table border="0" cellpadding="0" cellspacing="0"><tr>'+
								'<td><span dojoAttachPoint="iconNode"></span></td>' + 
								'<td><span class="swtLabelNode" dojoAttachPoint="labelNode">${label}</span><td>' +
								'<tr><table>'+
							'</td>' +
						'</tr></table>' +
					'</div>',
				getNativeBounds: function(){
					var containerNodeBounds = $wnd.swt.getNativeBounds(this.containerNode);
					var domNodeMarginExtends = $wnd.dojo._getMarginExtents(this.domNode);
					var domNodePadBorderExtends = $wnd.dojo._getPadBorderExtents(this.domNode);
					return $wnd.dojo.mixin(containerNodeBounds, {
						w: containerNodeBounds.w + domNodeMarginExtends.w + domNodePadBorderExtends.w,
						h: containerNodeBounds.h + domNodeMarginExtends.h + domNodePadBorderExtends.h
					});
				},
				postCreate: function(){
					this.domNode.parentNode ? this.name = this.domNode.parentNode.id : this.id;
					this.inherited("postCreate",arguments);
 					$wnd.swt.setCssStyle(this.domNode, {border: this.border});
				},
				resize: function(){},
				setAlignment: function(alignment){
					this.alignNode.width = "100%";
					this.alignNode.align = alignment; 
				},
				setImage: function(image){
					this.iconNode.innerHTML = "<img src='"+image+"'/>";
				},
				setLabel: function(content){
					this.labelNode.innerHTML = this.label = content;
				},
				setWidgetBounds: function(dim){
					$wnd.swt.setBounds(this.containerNode, {
						h: $wnd.swt.setBounds(this.domNode, dim).h
					});
				}
			});
		}
	}
	if((style & (@org.eclipse.swt.SWT::PUSH)) != 0 || style==@org.eclipse.swt.SWT::NONE) {
		if(!$wnd.dojo._hasResource["org.eclipse.swt.Button"]){
			$wnd.dojo._hasResource["org.eclipse.swt.Button"] = true;
			$wnd.dojo.provide("org.eclipse.swt.Button");
			
			$wnd.dojo.require("dijit.form.Button");
		
			$wnd.dojo.declare("org.eclipse.swt.Button", $wnd.dijit.form.Button, {
				border: "",
				staticClass: "swtControl",
				wrap: "",
				getNativeBounds: function(){
					var containerNodeBounds = $wnd.swt.getNativeBounds(this.focusNode);
					var domNodeMarginExtends = $wnd.dojo._getMarginExtents(this.domNode);
					var domNodePadBorderExtends = $wnd.dojo._getPadBorderExtents(this.domNode);
					return $wnd.dojo.mixin(containerNodeBounds, {
						w: containerNodeBounds.w + domNodeMarginExtends.w + domNodePadBorderExtends.w,
						h: containerNodeBounds.h + domNodeMarginExtends.h + domNodePadBorderExtends.h
					});
				},
				postCreate: function(){
					this.inherited("postCreate",arguments); 
					$wnd.swt.setCssStyle(this.domNode, {border: this.border});
					$wnd.swt.setCssStyle(this.focusNode, {padding: "0px"});
				},
				resize: function(){},
				setAlignment: function(alignment){
					$wnd.swt.setCssStyle(this.titleNode, {textAlign: alignment});
				},
				setImage: function(image){
					this.iconNode.innerHTML = "<img src='"+image+"'/>";
				},
				setLabel: function(content){
					this.containerNode.innerHTML = this.label = content;
					$wnd.swt.setCssStyle(this.containerNode, {whiteSpace: this.wrap});
				},
				setWidgetBounds: function(dim){
					$wnd.swt.setBounds(this.focusNode, 
						$wnd.swt.setBounds(this.domNode, dim)
					);
				}
			});
		}
	}
	if((style & (@org.eclipse.swt.SWT::RADIO)) != 0) {
		if(!$wnd.dojo._hasResource["org.eclipse.swt.RadioButton"]){
			$wnd.dojo._hasResource["org.eclipse.swt.RadioButton"] = true;
			$wnd.dojo.provide("org.eclipse.swt.RadioButton");
			
			$wnd.dojo.require("dijit.form.CheckBox");
			$wnd.dojo.require("dijit.Menu");
		
			$wnd.dojo.declare("org.eclipse.swt.RadioButton", $wnd.dijit.form.RadioButton, {
				border: "",
				label: "",
				templateString:
					'<div class="dijitContainer" dojoAttachPoint="focusNode" dojoAttachEvent="onmouseover:_onMouse,onmouseout:_onMouse,onclick:_onClick"/>' +
						'<table dojoAttachPoint="containerNode" border="0" cellpadding="0" cellspacing="0"><tr>' +
							'<td>' +
							 	'<div dojoAttachPoint="stateNode" waiRole="presentation">' +
									'<input type="${type}" class="dijitReset dijitCheckBoxInput" dojoAttachPoint="inputNode">' +
								'</div>' + 
							'</td>' +
							'<td dojoAttachPoint="alignNode" >' +
								'<table border="0" cellpadding="0" cellspacing="0"><tr>'+
								'<td><span dojoAttachPoint="iconNode"></span></td>' + 
								'<td><span class="swtLabelNode" dojoAttachPoint="labelNode">${label}</span><td>' +
								'<tr><table>'+
							'</td>' +
						'</tr></table>' +
					'</div>',
				getNativeBounds: function(){
					var containerNodeBounds = $wnd.swt.getNativeBounds(this.containerNode);
					var domNodeMarginExtends = $wnd.dojo._getMarginExtents(this.domNode);
					var domNodePadBorderExtends = $wnd.dojo._getPadBorderExtents(this.domNode);
					return $wnd.dojo.mixin(containerNodeBounds, {
						w: containerNodeBounds.w + domNodeMarginExtends.w + domNodePadBorderExtends.w,
						h: containerNodeBounds.h + domNodeMarginExtends.h + domNodePadBorderExtends.h
					});
				},
				registerInGroup: function(){
					this.domNode.parentNode ? this.name = this.domNode.parentNode.id : this.id;
					(this._groups[this.name] = this._groups[this.name] || []).push(this);
				},				
				postCreate: function(){
					this.domNode.parentNode ? this.name = this.domNode.parentNode.id : this.id;
					this.inherited("postCreate",arguments);
 					$wnd.swt.setCssStyle(this.domNode, {border: this.border});
				},
				resize: function(){},
				setAlignment: function(alignment){
					this.alignNode.width = "100%";
					this.alignNode.align = alignment; 
				},
				setImage: function(image){
					this.iconNode.innerHTML = "<img src='"+image+"'/>";
				},
				setLabel: function(content){
					this.labelNode.innerHTML = this.label = content;
				},
				setWidgetBounds: function(dim){
					$wnd.swt.setBounds(this.containerNode, {
						h: $wnd.swt.setBounds(this.domNode, dim).h
					});
				},
			});
		}
	}
	if((style & (@org.eclipse.swt.SWT::TOGGLE)) != 0) {
		if(!$wnd.dojo._hasResource["org.eclipse.swt.ToggleButton"]){
			$wnd.dojo._hasResource["org.eclipse.swt.ToggleButton"] = true;
			$wnd.dojo.provide("org.eclipse.swt.ToggleButton");
			
			$wnd.dojo.require("dijit.form.Button");
		
			$wnd.dojo.declare("org.eclipse.swt.ToggleButton", $wnd.dijit.form.ToggleButton, {
				border: "",
				staticClass: "swtControl",
				wrap: "",
				getNativeBounds: function(){
					var containerNodeBounds = $wnd.swt.getNativeBounds(this.focusNode);
					var domNodeMarginExtends = $wnd.dojo._getMarginExtents(this.domNode);
					var domNodePadBorderExtends = $wnd.dojo._getPadBorderExtents(this.domNode);
					return $wnd.dojo.mixin(containerNodeBounds, {
						w: containerNodeBounds.w + domNodeMarginExtends.w + domNodePadBorderExtends.w,
						h: containerNodeBounds.h + domNodeMarginExtends.h + domNodePadBorderExtends.h
					});
				},
				postCreate: function(){
					this.inherited("postCreate",arguments); 
					$wnd.swt.setCssStyle(this.domNode, {border: this.border});
					$wnd.swt.setCssStyle(this.focusNode, {padding: "0px"});
				},
				resize: function(){},
				setAlignment: function(alignment){
					$wnd.swt.setCssStyle(this.titleNode, {textAlign: alignment});
				},
				setImage: function(image){
					this.iconNode.innerHTML = "<img src='"+image+"'/>";
				},
				setLabel: function(content){
					this.containerNode.innerHTML = this.label = content;
					$wnd.swt.setCssStyle(this.containerNode, {whiteSpace: this.wrap});
				},
				setWidgetBounds: function(dim){
					$wnd.swt.setBounds(this.focusNode, 
						$wnd.swt.setBounds(this.domNode, dim)
					);
				}
			});
		}
	}	
	
	var jsParent = parent.@org.eclipse.swt.widgets.Widget::jsObject;
	var params = {};
	if((style & (@org.eclipse.swt.SWT::BORDER)) != 0){
		params.border = "1px solid black";
	}
	if((style & (@org.eclipse.swt.SWT::ARROW)) != 0) {
		if((style & (@org.eclipse.swt.SWT::LEFT)) != 0) {
			params.label = "&#9664;";
		}
		else if((style & (@org.eclipse.swt.SWT::RIGHT)) != 0) {
			params.label = "&#9654;";
		}
		else if((style & (@org.eclipse.swt.SWT::UP)) != 0) {
			params.label = "&#9650;";
		}
		else if((style & (@org.eclipse.swt.SWT::DOWN)) != 0) {
			params.label = "&#9660;";
		}
		var self = new $wnd.org.eclipse.swt.ArrowButton(params);
	} else
	if((style & (@org.eclipse.swt.SWT::CHECK)) != 0) {
		var self = new $wnd.org.eclipse.swt.CheckBox(params);        	
	} else
	if((style & (@org.eclipse.swt.SWT::PUSH)) != 0) {
		var self = new $wnd.org.eclipse.swt.Button(params);
	} else
	if((style & (@org.eclipse.swt.SWT::RADIO)) != 0) {
		var self = new $wnd.org.eclipse.swt.RadioButton(params);        	
	} else
	if((style & (@org.eclipse.swt.SWT::TOGGLE)) != 0) {
		var self = new $wnd.org.eclipse.swt.ToggleButton(params);
	} else 
	if(style==@org.eclipse.swt.SWT::NONE){
		var self = new $wnd.org.eclipse.swt.Button(params);
	}
	try {
		this.@org.eclipse.swt.widgets.Widget::jsObject = self;
		jsParent.addChild(self);
//TODO implement this on the Java side code		
		if(self.registerInGroup) self.registerInGroup(); 
	} catch (e) {
//TODO Have to throw real exception for Java side also	
		$wnd.console.log(e);
	}
}-*/;

native boolean _getSelection () /*-{
	return this.@org.eclipse.swt.widgets.Widget::jsObject.checked;
}-*/;

native void _setAlignment (int alignment) /*-{
	if((alignment & (@org.eclipse.swt.SWT::LEFT)) != 0) {
		this.@org.eclipse.swt.widgets.Widget::jsObject.setAlignment("left");
	}
	else if((alignment & (@org.eclipse.swt.SWT::RIGHT)) != 0) {
		this.@org.eclipse.swt.widgets.Widget::jsObject.setAlignment("right");
	}
	else if((alignment & (@org.eclipse.swt.SWT::CENTER)) != 0) {
		this.@org.eclipse.swt.widgets.Widget::jsObject.setAlignment("center");
	}
	else if((alignment & (@org.eclipse.swt.SWT::UP)) != 0) {
		this.@org.eclipse.swt.widgets.Widget::jsObject.setAlignment("up");
	}
	else if((alignment & (@org.eclipse.swt.SWT::DOWN)) != 0) {
		this.@org.eclipse.swt.widgets.Widget::jsObject.setAlignment("down");
	}
}-*/;

native void _setImage (String image) /*-{
	this.@org.eclipse.swt.widgets.Widget::jsObject.setImage(image);	
}-*/;

native void _setSelection (boolean selected) /*-{
	this.@org.eclipse.swt.widgets.Widget::jsObject.setAttribute("checked", selected);
}-*/;

native void _setText (String string) /*-{
	this.@org.eclipse.swt.widgets.Widget::jsObject.setLabel(string);	
}-*/;

}
