/*******************************************************************************
 * 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.events.*;

public class Scale extends Control {
	int minimum = 0, maximum = 100, selection = 0, increment = 1, pageIncrement = 10;

public Scale (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) {
	return checkBits (style, SWT.HORIZONTAL, SWT.VERTICAL, 0, 0, 0, 0);
}

void createWidget (Display display, Widget parent, int style, int index) {
	super.createWidget (display, parent, style, index);
	this.setValues(selection, minimum, maximum, increment, pageIncrement);
}

public int getIncrement () {
	checkWidget ();
	return increment;
}

public int getMaximum () {
	checkWidget ();
	return maximum;
}

public int getMinimum () {
	checkWidget ();
	return minimum;
}

public int getPageIncrement () {
	checkWidget ();
	return pageIncrement;
}

public int getSelection () {
	checkWidget ();
	return selection;
}

void hookEvents () {
	super.hookEvents();
	_hookSetValue("setValue");
}

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);	
}

void sendSelection (int selection) {
	setSelection(selection);
	sendEvent (SWT.Selection);
}

public void setIncrement (int value) {
	if(value==this.increment) return;
	setValues(selection, minimum, maximum, value, pageIncrement);
}

public void setMaximum (int value) {
	if(value==this.maximum) return;
	setValues(selection, minimum, value, increment, pageIncrement);
}

public void setMinimum (int value) {
	if(value==this.minimum) return;
	setValues(selection, value, maximum, increment, pageIncrement);
}

public void setPageIncrement (int value) {
	if(value==this.pageIncrement) return;
	setValues(selection, minimum, maximum, increment, value);
}

public void setSelection (int value) {
	if(value==this.selection) return;
	setValues(value, minimum, maximum, increment, pageIncrement);
}

void setValues (int selection, int minimum, int maximum, int increment, int pageIncrement) {
	checkWidget ();
	if (maximum <= minimum) return;
	if (increment < 1) return;
	if (pageIncrement < 1) return;
	selection = Math.min (Math.max (minimum, selection), maximum);
	this.selection = selection;
	this.minimum = minimum;
	this.maximum = maximum;
	this.increment = increment;
	this.pageIncrement = pageIncrement;
	_setValues(selection, minimum, maximum, increment, pageIncrement);
}

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

protected native void _createHandle (Widget parent, int style, int index) /*-{
	if((style & (@org.eclipse.swt.SWT::VERTICAL)) == 0) {
		if(!$wnd.dojo._hasResource["org.eclipse.swt.HorizontalScale"]){
			$wnd.dojo._hasResource["org.eclipse.swt.HorizontalScale"] = true;
			$wnd.dojo.provide("org.eclipse.swt.HorizontalScale");
			
			$wnd.dojo.require("dijit.form.Slider");
			
			$wnd.dojo.declare("org.eclipse.swt.HorizontalScale", $wnd.dijit.form.HorizontalSlider, {
				_increment: 1,
				border: "",
				bottomDecorationObj: "",
				topDecorationObj: "",
				constructor: function() {
					this.bottomDecorationObj = {};
					this.topDecorationObj = {};
        		},
        		increment: function(e){
        			this._bumpValue (e.keyCode==$wnd.dojo.keys.PAGE_UP ? this.pageIncrement : this._increment);
				},
        		decrement: function(e){
        			this._bumpValue (e.keyCode==$wnd.dojo.keys.PAGE_DOWN ? - this.pageIncrement : - this._increment);
				},
				postCreate: function(){
					this.domNode.style.border = this.border;
					this.inherited("postCreate",arguments);
					$wnd.dojo.addClass(this.domNode, "swtHorizontalScale");
					this.topDecorationObj = new $wnd.dijit.form.HorizontalRule({ruleStyle: "height:5px;"});
					$wnd.dojo.place(this.topDecorationObj.domNode, this.topDecoration, "first");
					this.bottomDecorationObj = new $wnd.dijit.form.HorizontalRule({ruleStyle: "height:5px;"}); 
					$wnd.dojo.place(this.bottomDecorationObj.domNode, this.bottomDecoration, "first");
					this.topDecorationObj.domNode.style.height = this.bottomDecorationObj.domNode.style.height = "0px"; 
				},
				resize: function(dim){},
				setValue: function(value, priorityChange){},
				setWidgetBounds: function(dim){
					$wnd.dojo.marginBox(this.domNode, {w: dim.w, l: dim.l, t: dim.t});
				},
				update: function(args) {
					this._increment=args.increment;
					this.minimum=args.minimum;
					this.maximum=args.maximum;
					this.discreteValues=args.discreteValues; 
					this.pageIncrement=args.pageIncrement; 
					
					$wnd.org.eclipse.swt.HorizontalScale.superclass.setValue.call(this, args.value);
						
					var count = parseInt((this.maximum - this.minimum)/this.pageIncrement) + 1;
					this.topDecorationObj.count = count;
					this.topDecorationObj.postCreate();
					this.bottomDecorationObj.count = count;
					this.bottomDecorationObj.postCreate();
				}
			});
		}
	}	
	if((style & (@org.eclipse.swt.SWT::VERTICAL)) != 0) {
		if(!$wnd.dojo._hasResource["org.eclipse.swt.VerticalScale"]){
			$wnd.dojo._hasResource["org.eclipse.swt.VerticalScale"] = true;
			$wnd.dojo.provide("org.eclipse.swt.VerticalScale");
			
			$wnd.dojo.require("dijit.form.Slider");
			
			$wnd.dojo.declare("org.eclipse.swt.VerticalScale", $wnd.dijit.form.VerticalSlider, {
				_increment: 1,
				border: "",
				leftDecorationObj: "",
				rightDecorationObj: "",
				constructor: function() {
					this.leftDecorationObj = {};
					this.rightDecorationObj = {};
        		},
        		decrement: function(e){
        			this._bumpValue (e.keyCode==$wnd.dojo.keys.PAGE_DOWN ? - this.pageIncrement : - this._increment);
				},
        		increment: function(e){
        			this._bumpValue (e.keyCode==$wnd.dojo.keys.PAGE_UP ? this.pageIncrement : this._increment);
				},
				postCreate: function(){
					this.domNode.style.border = this.border;
					this.inherited("postCreate",arguments); 
					$wnd.dojo.addClass(this.domNode, "swtVerticalScale");
					
					this.leftDecorationObj = new $wnd.dijit.form.VerticalRule({ruleStyle: "width:6px;margin-left:-2"}); 
					$wnd.dojo.place(this.leftDecorationObj.domNode, this.leftDecoration, "first");
					this.rightDecorationObj = new $wnd.dijit.form.VerticalRule({ruleStyle: "width:6px;margin-left:-4"}) 
					$wnd.dojo.place(this.rightDecorationObj.domNode, this.rightDecoration, "first");
				},
				resize: function(dim){},
				setValue: function(value, priorityChange){},
				setWidgetBounds: function(dim){
					$wnd.dojo.marginBox(this.domNode, {h: dim.h, l: dim.l, t: dim.t});
				},
				update: function(args) {
					this._increment=args.increment;
					this.minimum=args.minimum;
					this.maximum=args.maximum;
					this.discreteValues=args.discreteValues; 
					this.pageIncrement=args.pageIncrement; 

					$wnd.org.eclipse.swt.VerticalScale.superclass.setValue.call(this, args.value);
					
					var count = parseInt((this.maximum - this.minimum)/this.pageIncrement) + 1;
					this.leftDecorationObj.count = count;
					this.leftDecorationObj.postCreate();
					this.rightDecorationObj.count = count;
					this.rightDecorationObj.postCreate();
				}
			});
		}
	}
	
	var jsParent = parent.@org.eclipse.swt.widgets.Widget::jsObject;
	params = {};
	if((style & (@org.eclipse.swt.SWT::BORDER)) != 0){
		params.border = "1px solid black";
	}
	if((style & (@org.eclipse.swt.SWT::VERTICAL)) == 0){
		var self = new $wnd.org.eclipse.swt.HorizontalScale(params);
	}
	if((style & (@org.eclipse.swt.SWT::VERTICAL)) != 0){
		var self = new $wnd.org.eclipse.swt.VerticalScale(params);
	}
    try {
		this.@org.eclipse.swt.widgets.Widget::jsObject = self;
		jsParent.addChild(self);
	} catch (e) {
//TODO Have to throw real exception for Java side also	
		$wnd.console.log(e);
	}
}-*/;

native void _hookSetValue (String eventType) /*-{
	var self = this;
	$wnd.dojo.connect(
		self.@org.eclipse.swt.widgets.Widget::jsObject,
		eventType,
		function(arg){
			self.@org.eclipse.swt.widgets.Scale::sendSelection(I)(arg);
		}
	);
}-*/;

native void _setValues (int selection, int minimum, int maximum, int increment, int pageIncrement) /*-{
	this.@org.eclipse.swt.widgets.Widget::jsObject.update({
		discreteValues: (maximum - minimum + 1),
		increment: increment,
		minimum: minimum,
		maximum: maximum,
		pageIncrement: pageIncrement,
		value: selection
	});
}-*/;

}
