var Widgets = {};

(function() {
	function closeAllPromptDialog() {
		var event = document.createEvent('HTMLEvents');
		event.initEvent('PromptDialogClose', false, false);
		document.dispatchEvent(event);
	}
	
	function PromptDialog(options) {
		this.initialize(options);
	};
	
	PromptDialog.prototype = {
		initialize: function(options) {
			this.options = Object.extend({
				beforeShow: emptyFunction,
				afterShow:  emptyFunction,
				onCancel:   emptyFunction,
				onOK:		emptyFunction,
				onDestroy:  emptyFunction,
				placeIn:    document.body,
				elem:       null,					// elements to be shown in dialog
				showBtns:   true,
			}, options);
			
			if (!this.options.elem) {
				return;	
			}
			
			// close other prompt dialogs.
			closeAllPromptDialog();
			this.initBox();
			this.addEventListeners();
			this.show();
		},
		
		initBox: function() {
			this.box = document.createElement('div');
			this.box.className = 'prompt-dialog div-table full-size';
			var html = [];
			html.push('	<div>');
			html.push('		<div>');
			html.push('			<div class="prompt-container div-table" style="margin: auto;">');
			html.push('				<div>');
			html.push('					<div>');
			html.push('						<div class="prompt-btn-close prompt-btn"></div>');
			html.push('					</div>');
			html.push('				</div>');
			html.push('				<div><div class="prompt-content-box"></div></div>');
			html.push('				<div>');
			html.push('					<div>');
			html.push('						<a class="prompt-btn prompt-btn-ok" href="javascript: void(0);">OK</a>');
			html.push('						<a class="prompt-btn prompt-btn-cancel" href="javascript: void(0);">Cancel</a>');
			html.push('					</div>');
			html.push('				</div>');
			html.push('			</div>');
			html.push('		</div>');
			html.push('	</div>');
			this.box.innerHTML = html.join('');
			
			// hide buttons
			if (!this.options.showBtns) {
				this.box.className += ' hide-btns';
			}
			
			this.options.placeIn.appendChild(this.box);
		},
		
		addEventListeners: function() {
			var self = this;
			this.eventListeners = [];
			this.eventListeners.push({
				element: document,
				eventName: 'PromptDialogClose',
				func: function() {
					self.destroy();
				}
			});
			
			this.eventListeners.push({
				element: $(this.box).find('div.prompt-container')[0],
				eventName: 'mousedown',
				func: function(event) {
					event.stopPropagation();
				}
			});
			
			this.eventListeners.push({
				element: document,
				eventName: 'mousedown',
				func: function() {
					self.destroy();
				}
			});
			
			this.eventListeners.push({
				element: $(this.box).find('a.prompt-btn-cancel')[0],
				eventName: 'click',
				func: function(event) {
					self.options.onCancel();
					self.destroy();
				}	
			});
			
			this.eventListeners.push({
				element: $(this.box).find('a.prompt-btn-ok')[0],
				eventName: 'click',
				func: function(event) {
					if (false !== self.options.onOK()) {
						self.destroy();
					}
				}	
			});
			
			this.eventListeners.push({
				element: $(this.box).find('div.prompt-btn-close')[0],
				eventName: 'click',
				func: function(event) {
					self.destroy();
				}	
			});
			
			this.eventListeners.push({
				element: this.box,
				eventName: 'keypress',
				func: function(event) {
					if (event.keyCode == '27') {
						self.destroy();
					}
				}
			});
			
			for (var i = 0; i < this.eventListeners.length; i++) {
				var tmp = this.eventListeners[i];
				tmp.element.addEventListener(tmp.eventName, tmp.func, false);
			}
		},
		
		removeEventListeners: function() {
			if (!this.eventListeners)
				return;
				
			for (var i = 0; i < this.eventListeners.length; i++) {
				var tmp = this.eventListeners[i];
				tmp.element.removeEventListener(tmp.eventName, tmp.func, false);
			}
		},
		
		show: function() {
			this.options.beforeShow();
			$(this.box).find('div.prompt-content-box')[0].appendChild(this.options.elem);
			$(this.box).find('a.prompt-btn-ok')[0].focus();
			this.options.afterShow();		
		},
		
		destroy: function() {
			this.removeEventListeners();
			if (this.box) {
				$(this.box).remove();
				this.box = null;
			}
			this.options.onDestroy();
		}
	};
	
	Widgets.PromptDialog = PromptDialog;
})();

(function() {
	/**
	 * An wrapper of PromptDialog
	 */
	function IFramePromptDialog(options) {
		if (!options.location) {
			throw Error('location can not be null!');
		}

		this.initialize(options);
	}
	
	IFramePromptDialog.prototype = {
		initialize: function(options) {
			this.box = document.createElement('div');
			this.box.setAttribute('align', 'center');

			this.loading = document.createElement('div');
			this.loading.className = 'loading';
			this.showLoading();
			this.box.appendChild(this.loading);
						
			this.iframe = document.createElement('iframe');
			this.iframe.src = options.location;
			this.hideFrame();
			this.box.appendChild(this.iframe);
						
			var self = this;
			// Size to content
			$(this.iframe).bind("load", function() {
				self.iframe.width = self.iframe.contentWindow.document.documentElement.scrollWidth + 'px';
				self.iframe.height = self.iframe.contentWindow.document.documentElement.scrollHeight + 'px';
				
				// For UE concerning, show frame after 1 second.
				window.setTimeout(function() {
					self.hideLoading();
					self.showFrame();
				}, 1000);
			});
			
			this.promptDialog = new Widgets.PromptDialog(Object.extend(options, {
				elem: this.box,
				showBtns: false,
				onDestroy: function() {
					self.destroy();
				}
			}));
		},
		
		showLoading: function() {
			this.loading.style.display = 'block';	
		},
		
		hideLoading: function() {
			this.loading.style.display = 'none';
		},
		
		hideFrame: function() {
			this.iframe.style.position = 'absolute';
			this.iframe.style.top = '-100000px';
		},
		
		showFrame: function() {
			this.iframe.style.position = '';
			this.iframe.style.top = '';
		},
		
		destroy: function() {
			this.promptDialog = null;
			this.iframe = null;
			this.loading = null;
			this.box = null;
		}
	};
	
	Widgets.IFramePromptDialog = IFramePromptDialog;
})();


// var UndoMaker = 
(function() {
	var _undoCallback = null;
	var _onAutoHide = null;
	var _timeout = null;
	var _div = null;
	
	function _show(msg, callback, onAutohide) {
		_clearMsg();
		
		_undoCallback = callback;
		_onAutoHide = onAutohide;
		_div = document.createElement('div');
		_div.className = 'undo-box';
		_div.innerHTML = "<div>" + msg + "</div>";
		$(_div).click(_executeUndo);
		_$('info-box').appendChild(_div);
		_autoHide();
	}
	
	function _autoHide() {
		_timeout = window.setTimeout(function() {
			_clearMsg();
			if (typeof _onAutoHide == 'function') {
				_onAutoHide();
			}
		}, 5000);
	}
	
	function _executeUndo() {
		if (typeof _undoCallback != 'function') {
			return;
		}
		
		_undoCallback();
		_clearMsg();
	}
	
	function _clearMsg() {
		window.clearTimeout(_timeout);
		if (_div && _div.parentNode) {
			_div.parentNode.removeChild(_div);
		}
		_div = null;
	}
	
	Widgets.UndoMaker = {
		make: function(msg, callback, onAutoHide) {	
			if (typeof callback != 'function') {
				return;
			}
			
			_show(msg, callback, onAutoHide);
		}
	};
})();

// AppNameModifier 
(function() {
	var _originalElem = null;
	var _callback = null;
	var _input = null;
	
	function _keypress(event) {
		switch (event.keyCode) {
			// enter key
			case 13:
				_onChangeValue();
				break;
		}
	}
	
	function _blur(event) {
		_onChangeValue(event);
	}
	
	function _init(nameElem, callback) {
		if (_input) {
			_onChangeValue();
		}
		
		_callback = callback;
		_originalElem = nameElem;
		
		// hide original element
		_originalElem.style.display = 'none';
		
		// create an input for user to type new name.
		_input = document.createElement('input');
		_input.value = _originalElem.textContent;
		$(_input).click(function(event) {
			event.stopPropagation();
		});
		
		_originalElem.parentNode.appendChild(_input);
		_input.focus();
		_input.select();
		
		// Add event listeners.
		$(_input).keypress(_keypress);
		$(_input).blur(_blur);
		
		_callback.onStart();
	}
	
	function _onChangeValue() {
		_changeValue();
		_clear();
	}
	
	function _changeValue() {
		var value = _input.value.trim();
		if (!value || _originalElem.textContent == value) {
			_callback.onComplete(value);
			return;
		}
		
		// Because of class: text-ellipsis, if change textContent of original element, the element will not be re-rendered.
		// We have to clone a new element, make sure 'text-ellipsis' is applied.
		var newElem = document.createElement(_originalElem.tagName);
		newElem.className = _originalElem.className;
		newElem.textContent = value;
		_originalElem.parentNode.appendChild(newElem);
		$(_originalElem).remove();
		_originalElem = newElem;
		
		_callback.onComplete(value);
	}
	
	function _clear() {
		if (_input) {
			// Remove event listeners
			$(_input).unbind("keypress", _keypress);
			$(_input).unbind("blur", _blur);
			$(_input).remove();
			_input = null;
		}
		
		// Show original element
		if (_originalElem) {
			_originalElem.style.display = '';
		}
		
		_originalElem = null;
		_callback = null;
	}
	
	Widgets.AppNameModifier = {
		start: function(nameElem, callbacks) {
			_init(nameElem, Object.extend({
				onStart: emptyFunction,
				onComplete: emptyFunction
			}, callbacks));
		}
	};
})();