/*
  By Hangring
  #2008.11.01#
  ---
*/
if (typeof Diagram == 'undefined')
	throw new Error('Diagarm is not defined');

Diagram.Function = function (name /* : String */) {
	this.Name = name;
};

Diagram.Function.prototype = {
	Name : '',
	Comment : '',
	
	// class level
	Level : 0,
	
	// 容器, HTMLElement
	Container : null,
	// 说明信息
	CommentContainer : null,
	// 参数容器
	ArgumentsContainer : null,
	
	// Class.Frame
	Frame : null,
	// 关联的浮动对象, Diagram.Class 或 其他对象
	Popup : null,
	
	// private function
	_click : null,
	_mouseover : null,
	_mouseout : null,
	
	// public function
	Click : function () {},
	
	Create : function () {
		if (this.Name == '') throw new Error('Diagram.Function : Name is not empty');
		
		var c = this.Container = oNode.CreateNode('div');
		CSS.AddClass(c, 'function');
		
		var funcName, funcArgs, funcType;
		var arr = /([a-z_0-9]+?)\s*\((\d*)\)\s*:\s*([a-z_0-9]+)/i.exec(this.Name);
		var arr1 = /([a-z_0-9]+?)\s*\((\d*)\)/i.exec(this.Name);
		if (arr && arr.length > 1) {
			funcName = arr[1];
			funcArgs = arr[2];
			funcType = arr[3];
		}
		else if (arr1 && arr1.length > 1) {
			funcName = arr1[1];
			funcArgs = arr1[2];
			funcType = '';
		}
		else {
			funcName = this.Name;
			funcArgs = '';
			funcType = '';
		}
		
		var id = Global.Random();
		funcArgs = ['(', '<a href="javascript:;" id="function_args_', id, '" onclick="">', funcArgs, '</a>', ')'].join('');
		
		c.innerHTML = [
			// float left
			'<span class="function-name">', funcName, funcArgs, '</span>',
			// float right
			this.Comment != '' ? ['<span class="function-info">(<span id="function_info_', id, '" class="info-sign">i</span>)</span>'].join('') : '',
			'<span class="function-type">', funcType, (funcType ? '(<span class="type-sign" title="Return Type">T</span>)' : ''), '</span>'
		].join('');
		
		var self = this;
		var _click = this._click = function () {
			self.Click();
			if (self.Popup) {
				if (self.Popup.Container.Visible)
					CSS.AddClass(c, 'function-focus');
				else 
					CSS.RemoveClass(c, 'function-focus');
			}
		};
		var _mouseover = this._mouseover = function () {
			CSS.AddClass(c, 'function-over');
		};
		var _mouseout = this._mouseout = function () {
			CSS.RemoveClass(c, 'function-over');
		};
		
		Events.AttachEvent(c, 'click', _click);
		Events.AttachEvent(c, 'mouseover', _mouseover);
		Events.AttachEvent(c, 'mouseout', _mouseout);
		
		c.AddToStage = function () {
			$('function_args_' + id).onclick = function (e) {
				self.ArgumentsShow();
				Events.CancelAll(e);
			};
			
			$('function_info_' + id) && 
			($('function_info_' + id).onclick = function (e) {
				self.CommentShow();
				Events.CancelAll(e);
			});
		};
		
		return c;
	},
	
	// 如果Popup存在，则当Popup关闭时根据情况调用该方法
	PopupClose : function () {
		CSS.RemoveClass(this.Container, 'function-focus');
	},
	
	ArgumentsShow : function () {
		var ac = this.ArgumentsContainer = oNode.CreateNode('div');
		ac.Level = this.Level + 1;
		this.Frame.Popup.Add(ac, this.Level + 1);
		CSS.AddClass(ac, 'arguments');
		Global.SetPosition(ac, this.Container);
		ac.innerHTML = '参数说明';
		
		var close = oNode.CreateNode('span');
		oNode.InsertBefore(close, ac.firstChild);
		CSS.AddClass(close, 'close');
		close.innerHTML = 'x';
		close.onclick = function () {
			self.Frame.Popup.RemoveAllFromLevel(ac.Level);
		};
		
		var self = this;
		ac.Close = function () {
			self.Frame.Popup.RemovePopupFromContainer(this);
		};
	},
	
	ArgumentsHide : function () {
		this.ArgumentsContainer && 
		(this.ArgumentsContainer.style.visibility = 'hidden');
	},
	
	CommentShow : function () {
		var self = this;
		
		var cc = this.CommentContainer = oNode.CreateNode('div');
		cc.Level = this.Level + 1;
		this.Frame.Popup.Add(cc, this.Level + 1);
		CSS.AddClass(cc, 'comment');
		Global.SetPosition(cc, this.Container);
		
		cc.innerHTML = this.Comment.HtmlEntities();
		
		var close = oNode.CreateNode('span');
		oNode.InsertBefore(close, cc.firstChild);
		CSS.AddClass(close, 'close');
		close.innerHTML = 'x';
		close.onclick = function () {
			self.Frame.Popup.RemoveAllFromLevel(cc.Level);
		};
		
		cc.Close = function () {
			self.Frame.Popup.RemovePopupFromContainer(this);
		};
	},
	
	CommentHide : function () {
		this.CommentContainer && 
		(this.CommentContainer.style.visibility = 'hidden');
	}
}