/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.widget.ProgressBar");

dojo.require("dojo.widget.*");
dojo.require("dojo.event");
dojo.require("dojo.dom");
dojo.require("dojo.html.style");
dojo.require("dojo.string.*");
dojo.require("dojo.lfx.*");


dojo.widget.defineWidget(
	"dojo.widget.ProgressBar",
	dojo.widget.HtmlWidget,
	{
		// summary:
		// a progress widget, with some calculation and server polling capabilities
		//
		// description:
		// (implementation) four overlapped divs:
		// (1) lower z-index
		// (4) higher z-index
		// back and front percent label have the same content: when the vertical line (*)
		// partially hides the backPercentLabel, the frontPercentLabel becomes visible
		//
		//  ________________________(1)_containerNode_________________________________
		// |__(3)_internalProgress____________                                        |
		// |                                  | <--- (*)                              |
		// |     (4) frontPercentLabel        | (2) backPercentLabel                  |
		// |__________________________________|                                       |
		// |__________________________________________________________________________|
		//
		// usage:
		// <div dojoType="ProgressBar" frontBarClass="..." backBarClass="..."
		//   backBarClass="..." frontBarClass="..." duration="..."
		//   showOnlyIntegers="true|false" width="..." height="..." dataSource="..."
		//   pollInterval="..."
		//   hasText="true|false" isVertical="true|false"
		//   progressValue="..." maxProgressValue="..."></div>

		// progressValue: String
		// initial progress value.
		// with "%": percentual value, 0% <= progressValue <= 100%
		// or without "%": absolute value, 0 <= progressValue <= maxProgressValue
		progressValue: 0,

		// maxProgressValue: Float
		// max sample number
		maxProgressValue: 100,

		// width: Integer
		// ProgressBar width (pixel)
		width: 300,

		// height: Integer
		// ProgressBar height, (pixel)
		height: 30,

		// frontPercentClass: String
		// css class for frontPercentLabel (4)
		frontPercentClass: "frontPercent",

		// backPercentClass: String
		// css class for backPercentLabel (2)
		backPercentClass: "backPercent",

		// frontBarClass: String
		// css class for containerNode (1)
		frontBarClass: "frontBar",

		// backBarClass: String
		// css class for internalProgress (3)
		backBarClass: "backBar",

		// hasText: Boolean
		// if true, the percent label is visible
		hasText: false,

		// isVertical: Boolean
		// if true, the widget is vertical
		isVertical: false,

		// showOnlyIntegers: Boolean
		// if true, the percent label shows only integer values
		showOnlyIntegers: false,

		// dataSource: String
		// dataSource uri for server polling
		dataSource: "",

		// pollInterval: Integer
		// server poll interval
		pollInterval: 3000,

		// duration: Integer
		// duration of the animation
		duration: 1000,

		templatePath: dojo.uri.dojoUri("src/widget/templates/ProgressBar.html"),
		templateCssPath: dojo.uri.dojoUri("src/widget/templates/ProgressBar.css"),


		// attach points
		containerNode: null,
		internalProgress: null,

		// private members
		_pixelUnitRatio: 0.0,
		_pixelPercentRatio: 0.0,
		_unitPercentRatio: 0.0,
		_unitPixelRatio: 0.0,
		_floatDimension: 0.0,
		_intDimension: 0,
		_progressPercentValue: "0%",
		_floatMaxProgressValue: 0.0,
		_dimension: "width",
		_pixelValue: 0,
		_oInterval: null,
		_animation: null,
		_animationStopped: true,
		_progressValueBak: false,
		_hasTextBak: false,

		// public functions
		fillInTemplate: function(args, frag){
			this.internalProgress.className = this.frontBarClass;
			this.containerNode.className = this.backBarClass;
			if (this.isVertical){
				this.internalProgress.style.bottom="0px";
				this.internalProgress.style.left="0px";
				this._dimension = "height";
			} else {
				this.internalProgress.style.top="0px";
				this.internalProgress.style.left="0px";
				this._dimension = "width";
			}
			this.frontPercentLabel.className = this.frontPercentClass;
			this.backPercentLabel.className = this.backPercentClass;
			this.progressValue = "" + this.progressValue;
			this.domNode.style.height = this.height + "px";
			this.domNode.style.width = this.width + "px";
			this._intDimension = parseInt("0" + eval("this." + this._dimension));
			this._floatDimension = parseFloat("0" + eval("this."+this._dimension));
			this._pixelPercentRatio = this._floatDimension/100;
			this.setMaxProgressValue(this.maxProgressValue, true);
			this.setProgressValue(dojo.string.trim(this.progressValue), true);
			dojo.debug("float dimension: " + this._floatDimension);
			dojo.debug("this._unitPixelRatio: " + this._unitPixelRatio);
			this.showText(this.hasText);
		},
		showText: function(visible){
			// summary: shows or hides the labels
			if (visible){
				this.backPercentLabel.style.display="block";
				this.frontPercentLabel.style.display="block";
			} else {
				this.backPercentLabel.style.display="none";
				this.frontPercentLabel.style.display="none";
			}
			this.hasText = visible;
		},
		postCreate: function(args, frag){
			this.render();
		},
		_backupValues: function(){
			this._progressValueBak = this.progressValue;
			this._hasTextBak = this.hasText;
		},
		_restoreValues: function(){
				this.setProgressValue(this._progressValueBak);
				this.showText(this._hasTextBak);
		},
		_setupAnimation: function(){
			var _self = this;
			dojo.debug("internalProgress width: " + this.internalProgress.style.width);
			this._animation = dojo.lfx.html.slideTo(this.internalProgress,
				{top: 0, left: parseInt(this.width)-parseInt(this.internalProgress.style.width)}, parseInt(this.duration), null,
					function(){
						var _backAnim = dojo.lfx.html.slideTo(_self.internalProgress,
						{ top: 0, left: 0 }, parseInt(_self.duration));
						dojo.event.connect(_backAnim, "onEnd", function(){
							if (!_self._animationStopped){
								_self._animation.play();
							}
							});
						if (!_self._animationStopped){
							_backAnim.play();
						}
						_backAnim = null; // <-- to avoid memory leaks in IE
					}
				);
		},
		getMaxProgressValue: function(){
			// summary: returns the maxProgressValue
			return this.maxProgressValue;
		},
		setMaxProgressValue: function(maxValue, noRender){
			// summary: sets the maxProgressValue
			// if noRender is true, only sets the internal max progress value
			if (!this._animationStopped){
				return;
			}
			this.maxProgressValue = maxValue;
			this._floatMaxProgressValue = parseFloat("0" + this.maxProgressValue);
			this._pixelUnitRatio = this._floatDimension/this.maxProgressValue;
			this._unitPercentRatio = this._floatMaxProgressValue/100;
			this._unitPixelRatio = this._floatMaxProgressValue/this._floatDimension;
			this.setProgressValue(this.progressValue, true);
			if (!noRender){
				this.render();
			}
		},
		setProgressValue: function(value, noRender){
			// summary: sets the progressValue
			// if value ends width "%", does a normalization
			// if noRender is true, only sets the internal value: useful if
			// there is a setMaxProgressValue call
			if (!this._animationStopped){
				return;
			}
			// transformations here
			this._progressPercentValue = "0%";
			var _value=dojo.string.trim("" + value);
			var _floatValue = parseFloat("0" + _value);
			var _intValue = parseInt("0" + _value);
			var _pixelValue = 0;
			if (dojo.string.endsWith(_value, "%", false)){
				this._progressPercentValue = Math.min(_floatValue.toFixed(1), 100) + "%";
				_value = Math.min((_floatValue)*this._unitPercentRatio, this.maxProgressValue);
				_pixelValue = Math.min((_floatValue)*this._pixelPercentRatio, eval("this."+this._dimension));
			} else {
				this.progressValue = Math.min(_floatValue, this.maxProgressValue);
				this._progressPercentValue = Math.min((_floatValue/this._unitPercentRatio).toFixed(1), 100) + "%";
				_pixelValue = Math.min(_floatValue/this._unitPixelRatio, eval("this."+this._dimension));
			}
			this.progressValue = dojo.string.trim(_value);
			this._pixelValue = _pixelValue;
			if (!noRender){
				this.render();
			}
		},
		getProgressValue: function(){
			// summary: returns the progressValue
			return this.progressValue;
		},
		getProgressPercentValue: function(){
			// summary: returns the percentual progressValue
			return this._progressPercentValue;
		},
		setDataSource: function(dataSource){
			// summary: sets the dataSource
			this.dataSource = dataSource;
		},
		setPollInterval: function(pollInterval){
			// summary: sets the pollInterval
			this.pollInterval = pollInterval;
		},
		start: function(){
			// summary: starts the server polling
			var _showFunction = dojo.lang.hitch(this, this._showRemoteProgress);
			this._oInterval = setInterval(_showFunction, this.pollInterval);
		},
		startAnimation: function(){
			// summary: starts the left-right animation, useful when
			// the user doesn't know how much time the operation will last
			if (this._animationStopped) {
				this._backupValues();
				this.setProgressValue("10%");
				this._animationStopped = false;
				this._setupAnimation();
				this.showText(false);
				this.internalProgress.style.height="105%";
				this._animation.play();
			}
		},
		stopAnimation: function(){
			// summary: stops the left-right animation
			if (this._animation) {
				this._animationStopped = true;
				this._animation.stop();
				this.internalProgress.style.height="100%";
				this.internalProgress.style.left = "0px";
				this._restoreValues();
				this._setLabelPosition();
			}
		},
		_showRemoteProgress: function(){
			var _self = this;
			if ( (this.getMaxProgressValue() == this.getProgressValue()) &&
				this._oInterval){
				clearInterval(this._oInterval);
				this._oInterval = null;
				this.setProgressValue("100%");
				return;
			}
			var bArgs = {
				url: _self.dataSource,
				method: "POST",
				mimetype: "text/json",
				error: function(type, errorObj){
					dojo.debug("[ProgressBar] showRemoteProgress error");
				},
				load: function(type, data, evt){
					_self.setProgressValue(
						(_self._oInterval ? data["progress"] : "100%")
					);
				}
			};
			dojo.io.bind(bArgs);
		},
		render: function(){
			// summary: renders the ProgressBar, based on current values
			this._setPercentLabel(dojo.string.trim(this._progressPercentValue));
			this._setPixelValue(this._pixelValue);
			this._setLabelPosition();
		},

		_setLabelPosition: function(){
			var _widthFront =
				dojo.html.getContentBox(this.frontPercentLabel).width;
			var _heightFront =
				dojo.html.getContentBox(this.frontPercentLabel).height;
			var _widthBack =
				dojo.html.getContentBox(this.backPercentLabel).width;
			var _heightBack =
				dojo.html.getContentBox(this.backPercentLabel).height;
			var _leftFront = (parseInt(this.width) - _widthFront)/2 + "px";
			var _bottomFront = (parseInt(this.height) - parseInt(_heightFront))/2 + "px";
			var _leftBack = (parseInt(this.width) - _widthBack)/2 + "px";
			var _bottomBack = (parseInt(this.height) - parseInt(_heightBack))/2 + "px";
			this.frontPercentLabel.style.left = _leftFront;
			this.backPercentLabel.style.left = _leftBack;
			this.frontPercentLabel.style.bottom = _bottomFront;
			this.backPercentLabel.style.bottom = _bottomBack;
		},
		_setPercentLabel: function(percentValue){
			dojo.dom.removeChildren(this.frontPercentLabel);
			dojo.dom.removeChildren(this.backPercentLabel);
			var _percentValue = this.showOnlyIntegers == false ?
				percentValue : parseInt(percentValue) + "%";
			this.frontPercentLabel.
				appendChild(document.createTextNode(_percentValue));
			this.backPercentLabel.
				appendChild(document.createTextNode(_percentValue));
		},
		_setPixelValue: function(value){
			eval("this.internalProgress.style." + this._dimension + " = " + value + " + 'px'");
			this.onChange();
		},
		onChange: function(){
		}
	});

