/*
 * Copyright (c)  2006-2007 Maskat Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
maskat.lang.Class.declare("maskat.ui.JavaScriptProgressDialog")
	.extend("maskat.ui.ProgressDialog", {

	/**
	 * javascriptの進捗ダイアログコンストラクタ
	 *
	 * @param title ダイアログのタイトル文字列
	 * @param message ダイアログメッセージ文字列
	 * @param total 終了進捗値(オプション) または、doneを実行するまで終了しない処理中表示(POSITIVE_INFINITY)
	 */
	initialize: function (title, message, total) {
	
		/* 引数を内部メンバとして設定 */
		this.base.apply(this, arguments);
		
		/* totalのデフォルト設定 */
		if (!this.total || this.total == "") {
			this.total = 100;
		}
		
		/* 表示タイプの判定 */
		this.endlessMode = false;
		if (this.total == Number.POSITIVE_INFINITY) {
			this.endlessMode = true;
			this.total = 100;
		}
		
		/* 改行文字列の置換 */
		if (typeof(this.message) == "string") {
			this.message = this.message.replace( /\r?\n/g, "<br />\n");
		}
		
		/* ウインドウサイズを取得 (最小サイズ幅:500 高:50)  */
		this.getOffset (250, 50);
		/* 進捗バーの幅 */
		this.barWidth = this.width * 0.9;
		/* 進捗の最大値 */
		this.total = this.total ? this.total : 100;
		/* カレントの進捗値 */
		this.count = 0;
		/* 進捗バーのElement ID */
		this.barElementId = "";
		/* 進捗バーのElement ID */
		this.barElementId = "";
	},

	/**
	 * javascriptの進捗ダイアログをPOPUPして表示します。
	 *
	 */
	open: function () {
	
		/* ダイアログボックス表示 */
		if (!this.popup || this.popup.closed) {
			var windowParameter = "width=" + this.width;
			windowParameter += ",height=" + this.height;
			windowParameter += ",resizable=no,scrollbars=no,directories=no,location=no,menubar=no,status=no,toolbar=no";
			this.popup = window.open ("",
							this.title,
							windowParameter); 
		}else{
		    /*  既にウィンドウが開いている場合はフォーカスを当てる */
		    this.popup.focus();
		}
		
		/* Title, Bodyの設定 */
		bar = this.popup.document;
		bar.open();
		bar.write("<head><title>" + this.title + "</title></head>");
		bar.close();
		bar.bgColor = "#DCDCDC"
		
		/* メッセージの表示 */
		var divMsg = bar.createElement ("div");
		divMsg.id = 'processingMessage';
		divMsg.innerHTML = this.message;
		bar.body.appendChild(divMsg);
		
		/* 進捗バーの位置・サイズ算出 */
		var barHeight = 16; 
		this.barWidth = this.width * 0.9;
		var barTop = this.height - (barHeight + 20);
		var barLeft = this.width * 0.02;
		
		if (this.endlessMode) {
			
			/* 進捗バー表示枠の設定 */
			var barProgress = bar.createElement ("div");
			barProgress.id = 'pbar';
			barProgress.style.top = barTop;
			barProgress.style.left =(this.width - this.barWidth) / 2;
			barProgress.style.position = "absolute";

			/* 進捗バーの設定 */
			var imagePath = maskat.location + "core/images/"
			var imgTag = bar.createElement("img");
			imgTag.src = imagePath + "endless_progress.gif";
			imgTag.width = this.barWidth ;
			imgTag.height = 14;
			
			barProgress.appendChild(imgTag);
			bar.body.appendChild(barProgress);
		
		} else {
		
			/* 進捗率の表示 */
			var rateMargine = 35;
			this.barWidth = this.barWidth - rateMargine;
			this.textRate = bar.createElement ("div");
			this.textRate.id = "rate";
			this.textRate.innerHTML = "0%";
			this.textRate.style.position = "absolute";
			this.textRate.style.top = barTop;
			this.textRate.style.left = barLeft;
			bar.body.appendChild (this.textRate);
			
			/* 進捗バー枠の表示 */
			var divBar = bar.createElement ("div");
			divBar.id = 'barBorder';
			divBar.className = "progressBar";
			divBar.style.top = barTop;
			divBar.style.left = barLeft + rateMargine;
			divBar.style.width = this.barWidth;
			divBar.style.height = barHeight;
			divBar.style.backgroundColor = "white"; 
			divBar.style.borderColor = "black";
			divBar.style.borderStyle = "solid";
			divBar.style.borderWidth = "1px"; 
			divBar.style.position = "absolute";
			bar.body.appendChild(divBar);
			
			/* 進捗バーの設定 */
			var barColor = "#003399";
			var barProgress = bar.createElement ("div");
			barProgress.id = 'pbar';
			barProgress.style.top = barTop;
			barProgress.style.left = barLeft + rateMargine;
			barProgress.style.width = 0;
			barProgress.style.height = barHeight;
			barProgress.style.backgroundColor = barColor;
			barProgress.style.borderColor = barColor;
			barProgress.style.borderStyle = "solid";
			barProgress.style.borderWidth = "1px"; 
			barProgress.style.position = "absolute";
			bar.body.appendChild (barProgress);
		}
		return this.popup;

	},
	
	/**
	 * javascriptの進捗状況ウィンドウの進捗状況を更新します。
	 *
	 * @param count 進捗総数
	 */
	setProgress:function (count) {
		if (!this.isNumeric(count)) {
		    return;
		}
		this.count = count;
		/* トータルを超えている場合 */
		if (this.count > this.total) {
			this.count = this.total;
		}
		/* マイナス値の場合 */
		if (this.count < 0) {
			this.count = 0;
		}
		/* 表示の更新 */
		this.updateProgress();
		/* 終了時のClose */
		try {
		    this.popup.window.closed;
		} catch (e) {
		    this.popup = null;
		}
		if (this.count >= this.total) {
			if(this.popup) {
				this.popup.window.close();
				this.popup = null;
			}
		}
	},
	
	/**
	 * javascriptの進捗状況ウィンドウの進捗状況を加算更新します。
	 *
	 * @param addValue 進捗数
	 */
	worked:function (addValue) {
		if (this.isNumeric(addValue)) {
		    this.setProgress (Number(addValue) + Number(this.count));
		} else {
		    return;
		}
	},
	
	/**
	 * 進捗状況ウィンドウを閉じます。
	 *
	 */
	done: function() {
		this.setProgress(this.total);
	},
	
	/**
	 * 進捗状況ウィンドウの進捗状況を更新します。
	 *
	 */
	updateProgress: function () {
	
		/* 進捗率表示無し */
		if (this.endlessMode) {
			return;
		}
		/* 更新対象の存在チェック */
		if (!this.popup || this.popup.closed) {
		    return;
		}else{
		    this.popup.focus();
		}
		/* 進捗率の計算 */
		var rate = this.count * 100 / this.total;
		this.popup.document.getElementById ('rate').innerHTML 
					= Math.round (rate) + "%"; 
		/* 進捗バーの更新 */
		this.popup.document.getElementById ('pbar').style.width 
					= (this.barWidth * rate) / 100;

	},
	
	/**
	 * ダイアログサイズを算出します
	 *
	 * @param minWidth 最小幅
	 * @param minHeight 最小高さ
	 */
	getOffset: function (minWidth, minHeight) {
		var div = document.createElement("DIV");
		div.innerHTML = this.message;
		div.style.position = "absolute";
		div.style.visibility = "hidden";
		div.style.whiteSpace = "nowrap";
		document.body.appendChild(div);
		this.width = div.offsetWidth < minWidth ? minWidth : div.offsetWidth + 0;
		this.width = this.width * 1.05;
		this.height = div.offsetHeight < minHeight ? minHeight : div.offsetHeight;
		this.height += 50;
		document.body.removeChild(div);
		div = null;
	},

	/**
	 * 先頭にプラス・マイナスを含んだ数字であることをチェックします。
	 *
	 */
	isNumeric: function (value) {
	    if (typeof(value) != "string") { 
	        return true;
	    }
		return value.match(/[^+^-][\D]/g) ? false : true;
	},
	
	/**
	 * 表示中のメッセージを置き換えます
	 * 制限として、メッセージの長さによるウィンドウのリサイズは行いません
	 *
	 * @param newMessage 置き換え後のメッセージ
	 */
	replaceMessage: function (newMessage) {

		if (!this.popup || this.popup.closed) {
			/* ウィンドウが無いので無視 */
			return;
		}else{
		    /*  フォーカスを当てる */
		    this.popup.focus();
		}
	
		if (typeof(newMessage) != "string") { 
			return true;
		}

		var bar = this.popup.document;
		
		newMessage = newMessage.replace( /\r?\n/g, "<br />\n"); 
		bar.getElementById('processingMessage').innerHTML = newMessage;
	}

});
