// ==UserScript==
// @name		USWidgetManager
// @namespace	http://www.kanasansoft.com/
// @description this manage display of user script widget.
// @include		*
// ==/UserScript==

(function(){

	//common constant
	var DEBUG_FLAG=false;
	var SYNCHRONIZE_INTERVAL=5000;

/*	var IMAGE_URI_TITLE_BACKGROUND=
		"data:image/gif;base64,"+
		"R0lGODdhEAAQAOcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoKCgsL"+
		"CwwMDA0NDQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZGRoaGhsb"+
		"GxwcHB0dHR4eHh8fHyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygoKCkpKSoqKisr"+
		"KywsLC0tLS4uLi8vLzAwMDExMTIyMjMzMzQ0NDU1NTY2Njc3Nzg4ODk5OTo6Ojs7"+
		"Ozw8PD09PT4%2BPj8%2FP0BAQEFBQUJCQkNDQ0REREVFRUZGRkdHR0hISElJSUpK"+
		"SktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVVVVZWVldXV1hYWFlZWVpa"+
		"WltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdnZ2hoaGlpaWpq"+
		"amtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNzc3R0dHV1dXZ2dnd3d3h4eHl5eXp6"+
		"ent7e3x8fH19fX5%2Bfn9%2Ff4CAgIGBgYKCgoODg4SEhIWFhYaGhoeHh4iIiImJ"+
		"iYqKiouLi4yMjI2NjY6Ojo%2BPj5CQkJGRkZKSkpOTk5SUlJWVlZaWlpeXl5iYmJ"+
		"mZmZqampubm5ycnJ2dnZ6enp%2Bfn6CgoKGhoaKioqOjo6SkpKWlpaampqenp6io"+
		"qKmpqaqqqqurq6ysrK2tra6urq%2Bvr7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7"+
		"i4uLm5ubq6uru7u7y8vL29vb6%2Bvr%2B%2Fv8DAwMHBwcLCwsPDw8TExMXFxcbG"+
		"xsfHx8jIyMnJycrKysvLy8zMzM3Nzc7Ozs%2FPz9DQ0NHR0dLS0tPT09TU1NXV1d"+
		"bW1tfX19jY2NnZ2dra2tvb29zc3N3d3d7e3t%2Ff3%2BDg4OHh4eLi4uPj4%2BTk"+
		"5OXl5ebm5ufn5%2Bjo6Onp6erq6uvr6%2Bzs7O3t7e7u7u%2Fv7%2FDw8PHx8fLy"+
		"8vPz8%2FT09PX19fb29vf39%2Fj4%2BPn5%2Bfr6%2Bvv7%2B%2Fz8%2FP39%2Ff"+
		"7%2B%2Fv%2F%2F%2FywAAAAAEAAQAAAIbwD%2FCRxIsOA%2FdwgTKlzorpvDhxAj"+
		"dmNGsaLFi8x2adzIseMuVSBDihypKpPJkyhTZkLEsqXLl4juyJxJs%2BYdMzhz6t"+
		"xpporPn0CDViFCtKjRo0RmKF3KtOkMEVCjSp0qIoLVq1izRgDAtavXrwACAgA7";*/
	var IMAGE_URI_TITLE_BACKGROUND=
		"data:image/gif;base64,"+
		"R0lGODlhEAAQAOMPAAAAABERESIiIjMzM0RERFVVVWZmZnd3d4iIiJmZmaqqqru7"+
		"u8zMzN3d3e7u7v%2F%2F%2FywAAAAAEAAQAAAENpDJSStbOOvNu1ZgKI5kKSZoqq"+
		"5sqyJwLM90LR94ru98rxvAoHBILAoLyKRyyWwqCdCodEqIAAA7";
	var IMAGE_URI_DISPOSE_DOCK=
		"data:image/gif;base64,"+
		"R0lGODlhDAAMAOMLAAAAAGZmZnd3d4iIiJmZmaqqqru7u8zMzN3d3e7u7v%2F%2F"+
		"%2F%2F8AAP8AAP8AAP8AAP8AACH5BAEKAA8ALAAAAAAMAAwAAAQ%2B8D1AK5VT6a"+
		"3BTIlFgRQCIGh6UgdwvLBLGYBh3zVVAEXv8xQCgEAsDikDwGDJVFIEAhEA6gEErt"+
		"irRyK9PCIAOw%3D%3D";
	var IMAGE_URI_OPEN_SETTING=
		"data:image/gif;base64,"+
		"R0lGODlhDAAMAOMLAAAAAGZmZnd3d4iIiJmZmaqqqru7u8zMzN3d3e7u7v%2F%2F"+
		"%2F%2F8AAP8AAP8AAP8AAP8AACH5BAEKAA8ALAAAAAAMAAwAAAQ38D1AK5VT6a3B"+
		"TJYFAkhYlcCRpmpLGQBsyDFVAHd15wRA%2FEAfZQAYGI9FisCk9AAC0CjUI2FSIw"+
		"A7";
	var IMAGE_URI_RADIO_OFF=
		"data:image/gif;base64,"+
		"R0lGODlhDAAMAKEDAAAAAGZmZszMzP%2F%2F%2FyH5BAEKAAMALAAAAAAMAAwAAA"+
		"IdnI%2BpCw0chAgPgShnNSDnPXSeAF4elZga4yzuixQAOw%3D%3D";
	var IMAGE_URI_RADIO_ON=
		"data:image/gif;base64,"+
		"R0lGODlhDAAMAKEDAAAAAGZmZszMzP%2F%2F%2FyH5BAEKAAMALAAAAAAMAAwAAA"+
		"IfnI%2BpCw0chAgPgRhwNWC2uA0ddQlhmXlJqSpOuMRyAQA7";
	var IMAGE_URI_CHECK_OFF=
		"data:image/gif;base64,"+
		"R0lGODlhDAAMAKEBAAAAAMzMzMzMzMzMzCH5BAEKAAIALAAAAAAMAAwAAAIclI%2"+
		"BpCe2NQJgURFovDvbI3RkfFgpj5j3OwrZGAQA7";
	var IMAGE_URI_CHECK_ON=
		"data:image/gif;base64,"+
		"R0lGODlhDAAMAKECAAAAAGZmZszMzMzMzCH5BAEKAAMALAAAAAAMAAwAAAIjnI%2"+
		"BJAQkPGQJBCCbaefXlyYTflnmjAVyUpaHWew7Q3Cr2bRQAOw%3D%3D";
	var IMAGE_URI_RELOAD=
		"data:image/gif;base64,"+
		"R0lGODlhDAAMAKEBAAAAAMzMzMzMzMzMzCH5BAEKAAIALAAAAAAMAAwAAAIglI8p"+
		"waELInAozDaPpWb33HkQtYFiyXnWVV0S2IXMoxQAOw%3D%3D";

	var POSITION={
		X:{LEFT:"left",CENTER:"center",RIGHT:"right"},
		Y:{TOP:"top",MIDDLE:"middle",BOTTOM:"bottom"}
	}

	var DOCK_POSITION_COMBINATION=
		[
			{"x":POSITION.X.LEFT,"y":POSITION.Y.TOP},
			{"x":POSITION.X.RIGHT,"y":POSITION.Y.TOP},
			{"x":POSITION.X.LEFT,"y":POSITION.Y.BOTTOM},
			{"x":POSITION.X.RIGHT,"y":POSITION.Y.BOTTOM}
		];

	//common function
	var debug
		=function(output,forceflg){
			if(DEBUG_FLAG||forceflg){
				GM_log(output);
			}
		}

	var map
		=function(ary,mthd){
			var rtn=[];
			var len=ary.length;
			for(var i=0;i<len;i++){
				rtn.push(mthd(ary[i]));
			}
			return rtn;
		}

	function closurize(scope,method){
		var _scope=scope;
		return function(){
			return method.apply(_scope,arguments);
		}
	}

/*
	//recursive call version
	var getCartesianProduct
		=function(){
			if(arguments.length==0){return [[]]}
			//arguments.slice is not a function
			var args=[];
			for(var i=1;i<arguments.length;i++){
				args.push(arguments[i]);
			}
			var ary=arguments.callee.apply(this,args);
			var rtn=[];
			for(var i=0;i<arguments[0].length;i++){
				for(var j=0;j<ary.length;j++){
					rtn.push([arguments[0][i]].concat(ary[j]));
				}
			}
			return rtn;
		}
*/
	var getCartesianProduct
		=function(){

			var args=arguments;
			var argslen=args.length;
			var lens=[];
			var cur=[];
			for(var i=0;i<argslen;i++){
				lens.push(args[i].length);
				cur.push(0);
			}

			var flg=true;
			var arys=[];
			while(flg){
				var buf=[];
				for(var i=0;i<cur.length;i++){
					buf.push(args[i][cur[i]]);
				}
				arys.push(buf);
				for(var i=cur.length-1;i>=0;i--){
					cur[i]++;
					if(cur[i]<lens[i]){
						break;
					}else if(i!=0){
						cur[i]=0;
					}else{
						flg=false;
					}
				}
			}

			return arys;

		}

	var StoredDataManager
		=function(names){
			this.names=[];
			this.reservedWords=["synchronizeDate"];
			this.values={};
			var _reservedWords={};
			for(var i=0;i<this.reservedWords.length;i++){
				_reservedWords[this.reservedWords[i]]=true;
			}
			for(var i=0;i<names.length;i++){
				if(names[i] in _reservedWords){
					debug("StoredDataManager:"+
						  names[i]+" is reserved words.");
					return;
				}
			}
			for(var i=0;i<names.length;i++){
				this.names.push(names[i]);
			}
			this.load();
		}

	StoredDataManager.prototype.isSynchronized
		=function(){
			return (this["synchronizeDate"]==GM_getValue("synchronizeDate"));
		}

	StoredDataManager.prototype.isAllowedDataName
		=function(name){
			return (name in this.values);
		}

	StoredDataManager.prototype.load
		=function(){
			debug("StoredDataManager#load:start");
			for(var i=0;i<this.names.length;i++){
				this.values[this.names[i]]=GM_getValue(this.names[i]);
			}
			for(var i=0;i<this.reservedWords.length;i++){
				this[this.reservedWords[i]]=GM_getValue(this.reservedWords[i]);
			}
		}

	StoredDataManager.prototype.save
		=function(){
			this.synchronizeDate=String((new Date()).getTime());
			debug("StoredDataManager#save:start");
			for(var i=0;i<this.names.length;i++){
				GM_setValue(this.names[i],this.values[this.names[i]]);
			}
			for(var i=0;i<this.reservedWords.length;i++){
				GM_setValue(this.reservedWords[i],this[this.reservedWords[i]]);
			}
		}

	StoredDataManager.prototype.getDataByName
		=function(name){
			if(!this.isAllowedDataName(name)){
				debug("StoredDataManager#getDataByName:"+
					  name+" is not allowed data name.");
				return;
			}
			return this.values[name];
		}
	StoredDataManager.prototype.setDataByName
		=function(name,value){
			if(!this.isAllowedDataName(name)){
				debug("StoredDataManager#setDataByName:"+
					  name+" is not allowed data name.");
				return;
			}
			this.values[name]=value;
		}

	var getInnerText
		=function(ele){
			var val;
			switch(true){
			case ("innerText" in ele)	:	val=ele.innerText	;	break	;
			case ("textContent" in ele)	:	val=ele.textContent	;	break	;
			default						:						;	break	;
			}
			return val;
		}

	var setInnerText
		=function(ele,val){
			switch(true){
			case ("innerText" in ele)	:	ele.innerText=val	;	break	;
			case ("textContent" in ele)	:	ele.textContent=val	;	break	;
			default						:						;	break	;
			}
		}

	var setInitialStyle
		=function(ele){
			var style=
				"color:#000000;"+
				"background:transparent none repeat scroll left top;"+
				"font:normal normal normal 12px/100% serif;"+
				"margin:0px;padding:0px;border:0px solid transparent;"+
				"display:block;position:static;float:none;clear:none;"+
				"top:auto;left:auto;bottom:auto;right:auto;z-index:;"+
				"width:auto;height:auto;vertical-align:text-bottom;"+
				"overflow:visible;clip:auto;visibility:inherit;"+
				"text-indent:0em;text-align:left;text-decoration:none;"+
				"white-space:normal;cursor:auto;opacity:1.0;";
			ele.setAttribute("style",style);
		}

	var getDisplayPosition
		=(function(){
			var objTopLeft;
			var objBottomRight;
			return function(obj){

				if(!objTopLeft){
					objTopLeft=document.createElement("div");
					var body=document.getElementsByTagName("body")[0];
					body.appendChild(objTopLeft);
				}
				if(!objBottomRight){
					objBottomRight=document.createElement("div");
					var body=document.getElementsByTagName("body")[0];
					body.appendChild(objBottomRight);
				}

				setInitialStyle(objTopLeft);
				objTopLeft.style.visibility="hidden";
				objTopLeft.style.position="fixed";
				objTopLeft.style.top="0px";
				objTopLeft.style.left="0px";
				setInitialStyle(objBottomRight);
				objBottomRight.style.visibility="hidden";
				objBottomRight.style.position="fixed";
				objBottomRight.style.bottom="0px";
				objBottomRight.style.right="0px";

				var rtn={};
				rtn.height=obj.offsetHeight;
				rtn.width=obj.offsetWidth;
				rtn.top=obj.offsetTop-objTopLeft.offsetTop;
				rtn.left=obj.offsetLeft-objTopLeft.offsetLeft;
				rtn.bottom=objBottomRight.offsetTop-obj.offsetTop-obj.offsetHeight;
				rtn.right=objBottomRight.offsetLeft-obj.offsetLeft-obj.offsetWidth;

				return rtn;

			}
		})();

	var StringUtility
		=function(){
		}

	StringUtility.Encode
		=function(){
		}

	StringUtility.Decode
		=function(){
		}

	StringUtility.Convert
		=function(){
		}

	StringUtility.Encode.HTML
		=function(str){
			return str.
			replace(/&/ig,"&amp;").
			replace(/</ig,"&lt;").
			replace(/>/ig,"&gt;").
			replace(/'/ig,"&apos;").
			replace(/"/ig,"&quot;").
			replace(/ /ig,"&nbsp;");
		}

	StringUtility.Decode.HTML
		=function(str){
			return str.
			replace(/&nbsp;/ig," ").
			replace(/&quot;/ig,"\"").
			replace(/&apos;/ig,"'").
			replace(/&gt;/ig,">").
			replace(/&lt;/ig,"<").
			replace(/&amp;/ig,"&");
		}

	StringUtility.Encode.HTMLforBookmarklet
		=function(str){
			return str.
			replace(/&/ig,"&amp;").
			replace(/</ig,"&lt;").
			replace(/>/ig,"&gt;").
			replace(/'/ig,"&apos;").
			replace(/"/ig,"&quot;");
		}

	StringUtility.Encode.JavaScript
		=function(str){
			return str.
			replace(/\\/ig,"\\\\").
/*			replace(/\b/ig,"\\b").*/
			replace(/\f/ig,"\\f").
			replace(/\n/ig,"\\n").
			replace(/\r/ig,"\\r").
			replace(/\t/ig,"\\t").
			replace(/'/ig,"\\'").
			replace(/"/ig,"\\\"");
		}

	StringUtility.Encode.JavaScriptComplete
		=function(str){
			var rtn="";
			for(var i=0;i<str.length;i++){
				rtn+="\\u"+
					(("0000"+(str.charCodeAt(i).toString(16))).slice(-4));
			}
			return rtn;
		}

	StringUtility.Convert.TabToSpace
		=function(str,tabNumber){

			var linesRN=str.split("\r\n");
			for(var lineCntRN=0;lineCntRN<linesRN.length;lineCntRN++){
				var linesN=linesRN[lineCntRN].split("\n");
				for(var lineCntN=0;lineCntN<linesN.length;lineCntN++){
					var linesR=linesN[lineCntN].split("\r");
					for(var lineCntR=0;lineCntR<linesR.length;lineCntR++){
						var wordsT=linesR[lineCntR].split("\t");
						for(var wordsCntT=0;wordsCntT<wordsT.length-1;wordsCntT++){
							wordsT[wordsCntT]+=
							StringUtility.getRepeatString(
								" ",
								tabNumber-
									(StringUtility.getLengthByByte(
										wordsT[wordsCntT])%tabNumber
									)
							)
						}
						linesR[lineCntR]=wordsT.join("");
					}
					linesN[lineCntN]=linesR.join("\r");
				}
				linesRN[lineCntRN]=linesN.join("\n");
			}
			var	rtn=linesRN.join("\r\n");

			return rtn;

		}

	StringUtility.Convert.NewLineCodeToTag
		=function(str){
			return
			str.
			replace(/\r\n/ig,"<br />").
			replace(/\r/ig,"<br />").
			replace(/\n/ig,"<br />");
		}

	StringUtility.getLengthByByte
		=function(str){
			var count=0;
			for(var i=0;i<str.length;i++){
				var code=str.charCodeAt(i);
				while(code!=0){
					count++;
					code>>>=8;
				}
			}
			return count;
		}

	StringUtility.getRepeatString
		=function(str,num){
			var rtn="";
			for(var i=0;i<num;i++){
				rtn+=str;
			}
			return rtn;
		}

	var JSON=
		function(){}

	JSON.encode
		=function(obj){
			var rtn;
			if(obj==null){
				rtn="null";
			}else{
				switch(true){
				case (obj instanceof Boolean):
				case (typeof(obj)=="boolean"):
					rtn=obj?"true":"false";
					break;
				case (obj instanceof Number):
				case (typeof(obj)=="number"):
					rtn=isNaN(obj)||!isFinite(obj)?"null":obj.toString(10);
					break;
				case (obj instanceof String):
				case (typeof(obj)=="string"):
					rtn="\""+StringUtility.Encode.JavaScript(obj)+"\"";
					break;
				case (obj instanceof Array):
//				case (typeof(obj)=="array"):
					var buf=[];
					for(var i=0;i<obj.length;i++){
						buf.push(arguments.callee(obj[i]));
					}
					rtn="["+buf.join(",")+"]";
					break;
				case (obj instanceof Function):
				case (typeof(obj)=="function"):
					rtn="null";
					break;
				case (obj instanceof Object):
//				case (typeof(obj)=="object"):
					var buf=[];
					for(var key in obj){
						if(obj.hasOwnProperty(key)){
							buf[buf.length]=
								arguments.callee(key)+":"+
								arguments.callee(obj[key]);
						}
					}
					rtn="{"+buf.join(",")+"}";
					break;
				default:
					rtn="null";
					break;
				}
			}
			return rtn;
		}

	JSON.encodeComplete
		=function(obj){
			var rtn;
			if(obj==null){
				rtn="null";
			}else{
				switch(true){
				case (obj instanceof Boolean):
				case (typeof(obj)=="boolean"):
					rtn=obj?"true":"false";
					break;
				case (obj instanceof Number):
				case (typeof(obj)=="number"):
					rtn=isNaN(obj)||!isFinite(obj)?"null":obj.toString(10);
					break;
				case (obj instanceof String):
				case (typeof(obj)=="string"):
					rtn="\""+StringUtility.Encode.JavaScriptComplete(obj)+"\"";
					break;
				case (obj instanceof Array):
//				case (typeof(obj)=="array"):
					var buf=[];
					for(var i=0;i<obj.length;i++){
						buf.push(arguments.callee(obj[i]));
					}
					rtn="["+buf.join(",")+"]";
					break;
				case (obj instanceof Function):
				case (typeof(obj)=="function"):
					rtn="null";
					break;
				case (obj instanceof Object):
//				case (typeof(obj)=="object"):
					var buf=[];
					for(var key in obj){
						if(obj.hasOwnProperty(key)){
							buf[buf.length]=
								arguments.callee(key)+":"+
								arguments.callee(obj[key]);
						}
					}
					rtn="{"+buf.join(",")+"}";
					break;
				default:
					rtn="null";
					break;
				}
			}
			return rtn;
		}

	JSON.decode
		=function(str){
			var rtn;
			eval("rtn="+str);
			return rtn;
		}

	var USWidgetDock
		=function(){
			var body=document.getElementsByTagName("body")[0];
			var dock=document.createElement("div");
			body.appendChild(dock);
			this.dock=dock;
			this.dockIcons=[];
		}

	USWidgetDock.prototype.addDockIcon
		=function(dockIcon){
			this.dockIcons.push(dockIcon);
			this.dock.appendChild(dockIcon);
		}

	USWidgetDock.prototype.redraw
		=function(x,y,z){
			var dock=this.dock;
			setInitialStyle(dock);
			dock.style.position="fixed";
			dock.style.zIndex=z;
			switch(x){
			case POSITION.X.LEFT:dock.style.left="0px";break;
			case POSITION.X.RIGHT:dock.style.right="0px";break;
			}
			switch(y){
			case POSITION.Y.TOP:dock.style.top="0px";break;
			case POSITION.Y.BOTTOM:dock.style.bottom="0px";break;
			}
		}

	//main
	var USWidgetManager
		=function(){
			debug("USWidgetManager:start");
			if(!("_USWidgetManager_" in window)){
				window._USWidgetManager_={};
			}
			if(!("widgets" in window._USWidgetManager_)){
				window._USWidgetManager_.widgets=[];
			}
			if(!("events" in window._USWidgetManager_)){
				window._USWidgetManager_.events=[];
			}
			this.loadedWidgetNames=[];
			this.loadedWidgets={};
			this.loadedEvents={};
			this.loadedStyles={};
			this.baseZIndex=1000;
			this.initialProcessInformation();
			this.USWDock=new USWidgetDock();
			this.storedDataManager=new StoredDataManager(["datas"]);
			var storedData=this.storedDataManager.getDataByName("datas");
			storedData=storedData?JSON.decode(storedData):{};
			this.storedData=storedData;
			window._USWidgetManager_.noticeAddEvents=
				closurize(this,this.loadEvents);
			window._USWidgetManager_.noticeAddWidgets=
				closurize(this,this.loadWidgets);

/*
			window._USWidgetManager_.noticeAddEvents=
				(function(scope){
					debug("make closure noticeAddEvents");
					var _scope=scope;
					return function(){
						debug("inner closure noticeAddEvents");
						_scope.loadEvents();
					}
				})(this);
			window._USWidgetManager_.noticeAddWidgets=
				(function(scope){
					debug("make closure noticeAddWidgets");
					var _scope=scope;
					return function(){
						debug("inner closure noticeAddWidgets");
						_scope.loadWidgets();
					}
				})(this);
*/
			this.loadEvents();
			this.loadWidgets();
			this.redrawDock();

			GM_registerMenuCommand(
				"USWManager - reset",
				(function(scope){
					return function(){
						scope.storedData={};
						scope.saveStoredData();
					}
				})(this)
			);


			window.setInterval(
				(function(scope){
					var _scope=scope;
					return function(){
						debug("timer");
						_scope.synchronize.call(_scope);
					}
				})(this),
				SYNCHRONIZE_INTERVAL
			);

		}

	USWidgetManager.prototype.loadEvents
		=function(){

			debug("USWidgetManager#loadEvents:start");

			var unloadEvents=window._USWidgetManager_.events;
			var loadedEvents=this.loadedEvents;

			map(unloadEvents,
				function(unloadEvent){
					if(loadedEvents[unloadEvent.id]){
						var errstr=
							"\""+unloadEvent.name+
							"\" event is already loaded.";
						debug(errstr,unloadEvent.debugFlag);
						throw errstr;
					}
					loadedEvents[unloadEvent.id]=unloadEvent;
				}
			   );

			window._USWidgetManager_.events=[];

		}

	USWidgetManager.prototype.loadWidgets
		=function(){

			debug("USWidgetManager#loadWidgets:start");

			var body=document.getElementsByTagName("body")[0];
			var USWDock=this.USWDock;
			var unloadWidgets=window._USWidgetManager_.widgets;
			var loadedWidgets=this.loadedWidgets;
			var loadedWidgetNames=this.loadedWidgetNames;
			var initialStoredDatas=USWidget.getInitialStoredDatas();
			var storedDataNames=USWidget.getStoredDataNames();
			var getWidgetDatasById=closurize(this,this.getWidgetDatasById);
			var noticeDragStart=closurize(this,this.noticeDragStart);
			var noticeProcessEnd=closurize(this,this.noticeProcessEnd);
			var noticeChangeStoredDatas=
				closurize(this,this.noticeChangeStoredDatas);
			var noticeActivate=closurize(this,this.noticeActivate);
			var getCurrentEvents=closurize(this,this.getCurrentEvents);
			var getBaseZIndex=closurize(this,this.getBaseZIndex);

			map(unloadWidgets,
				function(unloadWidget){
					debug("USWidgetManager#loadedWidgets:unloadWidget.name:"+
						  unloadWidget.name);
					var widget=new USWidget(unloadWidget);
					debug("USWidgetManager#loadedWidgets:USWidget instanced.");
					if(loadedWidgets[widget.id]){
						var errstr=
							"\""+widget.name+
							"\" widget is already loaded.";
						debug(errstr,unloadWidget.debugFlag);
						throw errstr;
					}
					debug("USWidgetManager#loadedWidgets:"+
						  "getWidgetStoredDatesById");
					var widgetDatas=getWidgetDatasById(widget.id);
					debug("USWidgetManager#loadedWidgets:prepare datas.");
					var datas={};
						map(
						storedDataNames,
						function(name){
							datas[name]=widgetDatas[name]?
								widgetDatas[name]:initialStoredDatas[name];
						}
					);
					debug("USWidgetManager#loadedWidgets:datas:"+
						  JSON.encode(datas));
					widget.setStoredDatas(datas);
					debug("USWidgetManager#loadedWidgets:set closure.");
					widget.setNoticeDragStart(noticeDragStart);
					widget.setNoticeProcessEnd(noticeProcessEnd);
					widget.setNoticeChangeStoredDatas(noticeChangeStoredDatas);
					widget.setNoticeActivate(noticeActivate);
					widget.setGetCurrentEvents(getCurrentEvents);
					widget.setGetBaseZIndex(getBaseZIndex);
					debug("USWidgetManager#loadedWidgets:resetStyles");
					widget.resetStyles();
					debug("USWidgetManager#loadedWidgets:addEvent");
					widget.addEvent();
					debug("USWidgetManager#loadedWidgets:push widget");
					loadedWidgetNames.push(widget.id);
					debug("USWidgetManager#loadedWidgets:add widget");
					loadedWidgets[widget.id]=widget;
					debug("USWidgetManager#loadedWidgets:appendChild for Body");
					body.appendChild(widget.USWFrame);
					USWDock.addDockIcon(widget.USWDockIcon);
					widget.redraw();
					debug("USWidgetManager#loadedWidgets:loop break or continue.");
				}
			   );

			debug("USWidgetManager#loadedWidgets:widgets clear.");
			window._USWidgetManager_.widgets=[];

			debug("USWidgetManager#loadedWidgets:redraw.");
//			this.redraw();

			debug("USWidgetManager#loadWidgets:end");

		}

	USWidgetManager.prototype.saveStoredData
		=function(){
			debug("USWidgetManager#saveStoredData:start");
			var storedData=JSON.encode(this.storedData);
			this.storedDataManager.setDataByName("datas",storedData);
			if(this.getProcessName()!=USWidgetManager.PROCESS_NAME_SYNCHRONIZE){
				this.storedDataManager.save();
			}
		}

//	USWidgetManager.prototype.redraw
//		=function(){
//			this.USWDock.redraw();
//TODO
//		}

	USWidgetManager.prototype.synchronize
		=function(){
			debug("USWidgetManager#synchronize:start");
			if(this.storedDataManager.isSynchronized()){
				debug("USWidgetManager#synchronize:isSynchronized is true");
				return;
			}
			if(!this.noticeSynchronizeStart()){return;}
			var loadedWidgets=this.loadedWidgets;
			var loadedWidgetNames=this.loadedWidgetNames;
			var initialStoredDatas=USWidget.getInitialStoredDatas();
			this.storedDataManager.load();
			var storedData=this.storedDataManager.getDataByName("datas");
			storedData=storedData?JSON.decode(storedData):{};
			this.storedData=storedData;
			var storedDataNames=USWidget.getStoredDataNames();
			var getWidgetDatasById=closurize(this,this.getWidgetDatasById);
			map(loadedWidgetNames,
				function(loadedWidgetName){
					var widget=loadedWidgets[loadedWidgetName];
					var widgetDatas=getWidgetDatasById(widget.id);
					var datas={};
					map(
						storedDataNames,
						function(name){
							datas[name]=(name in widgetDatas)?
								widgetDatas[name]:initialStoredDatas[name];
						}
					);
					widget.setStoredDatas(datas);
					widget.redraw();
				}
			   );
			this.redrawDock();
			this.noticeProcessEnd();
		}

	USWidgetManager.prototype.noticeSynchronizeStart
		=function(){
			if(this.isProcessing()){
				return false;
			}
			this.setProcessInformation(
				{
					"processName":USWidgetManager.PROCESS_NAME_SYNCHRONIZE,
					"sourceType":"widgetmanager"
				}
			);
			return true;
		}

	USWidgetManager.prototype.noticeDragStart
		=function(widget){
			if(this.isProcessing()){
				return false;
			}
			this.setProcessInformation(
				{
					"processName":USWidgetManager.PROCESS_NAME_DRAG,
					"sourceType":"widget",
					"sourceId":widget.id
				}
			);
			return true;
		}

	USWidgetManager.prototype.noticeProcessEnd
		=function(widget){
			if(!this.isProcessing()){
				return false;
			}
			this.initialProcessInformation();
			return true;
		}

	USWidgetManager.prototype.setProcessInformation
		=function(processInformation){
			var requiredParameter=["processName"];
			var allowedParameter=["sourceType","sourceId"];
			var buf={};
			map(
				requiredParameter,
				function(param){
					if(param in processInformation){
						buf[param]=processInformation[param];
					}else{
						var errstr="process information require \""+param+"\".";
						debug(errstr);
						throw errstr;
					}
				}
			);
			map(
				allowedParameter,
				function(param){
					if(param in processInformation){
						buf[param]=processInformation[param];
					}
				}
			);
			this.process=buf;
		}

	USWidgetManager.prototype.initialProcessInformation
		=function(){
			this.setProcessInformation(
				{
					"processName":USWidgetManager.PROCESS_NAME_NONE
				}
			);
		}

	USWidgetManager.prototype.getProcessName
		=function(){
			return String(this.process.processName);
		}

	USWidgetManager.prototype.isProcessing
		=function(){
			return (this.getProcessName()!=USWidgetManager.PROCESS_NAME_NONE);
		}

	USWidgetManager.prototype.noticeChangeStoredDatas
		=function(widget){
			var storedDatas=widget.getStoredDatas();
			this.setWidgetDatasById(widget.id,storedDatas);
		}

	USWidgetManager.prototype.noticeActivate
		=function(widget){
			var loadedWidgetNames=this.loadedWidgetNames;
			for(var i=0;i<loadedWidgetNames.length;i++){
				var loadedWidget=this.loadedWidgets[loadedWidgetNames[i]];
				var otherZIndex=loadedWidget.getStoredDatas().zIndex;
				if(widget.getStoredDatas().zIndex<otherZIndex){
					loadedWidget.setStoredDatas({"zIndex":--otherZIndex});
					loadedWidget.redraw();
				}
			}
			widget.setStoredDatas(
				{"zIndex":loadedWidgetNames.length}
			);
			widget.redraw();
		}

	USWidgetManager.prototype.getWidgetDatasById
		=function(id){
			var storedData=this.storedData;
			if(!storedData){storedData={};}
			var widgets=storedData.widgets;
			if(!widgets){widgets={};}
			var widgetDatas=widgets[id];
			if(!widgetDatas){widgetDatas={};}
			var rtn={};
			for(var key in widgetDatas){
				rtn[key]=widgetDatas[key];
			}
			return rtn;
		}

	USWidgetManager.prototype.setWidgetDatasById
		=function(id,widgetDatas){
			if(!this.storedData){this.storedData={};}
			if(!this.storedData.widgets){this.storedData.widgets={};}
			var buf={};
			for(var key in widgetDatas){
				buf[key]=widgetDatas[key];
			}
			this.storedData.widgets[id]=buf;
			this.saveStoredData();
		}

	USWidgetManager.prototype.getDockDatas
		=function(){
			var storedData=this.storedData;
			if(!storedData){storedData={};}
			var dockDatas=storedData.dock;
			if(!dockDatas){dockDatas={};}
			var rtn={};
			for(var key in dockDatas){
				rtn[key]=dockDatas[key];
			}
			rtn["x"]=rtn["x"]?rtn["x"]:POSITION.X.LEFT;
			rtn["y"]=rtn["y"]?rtn["y"]:POSITION.Y.TOP;
			return rtn;
		}

	USWidgetManager.prototype.setDockDatas
		=function(dockDatas){
			if(!this.storedData){this.storedData={};}
			if(!this.storedData.dock){this.storedData.dock={};}
			var buf={};
			for(var key in dockDatas){
				buf[key]=dockDatas[key];
			}
			this.storedData.dock=buf;
			this.saveStoredData();
			this.redrawDock();
		}

	USWidgetManager.prototype.redrawDock
		=function(){
			var dockDatas=this.getDockDatas();
//			var x=dockDatas["x"]?dockDatas["x"]:POSITION.X.LEFT;
//			var y=dockDatas["y"]?dockDatas["y"]:POSITION.Y.TOP;
			this.USWDock.redraw(dockDatas.x,dockDatas.y,this.getBaseZIndex());
		}

	USWidgetManager.prototype.getCurrentEvents
		=function(){
			var currentEvents=this.loadedEvents[this.getCurrentEventId()];
			if(!currentEvents){
				currentEvents=
					this.loadedEvents["default"]?
					this.loadedEvents["default"]:
					{};
			}
			var eventsBody=currentEvents.events;
			return eventsBody?eventsBody:{};
		}

	USWidgetManager.prototype.setCurrentEventId
		=function(id){
			if(!this.loadedEvents[id]){
				id="default";
			}
			this.storedData.currentEventId=id;
			this.saveStoredData();
		}

	USWidgetManager.prototype.getCurrentEventId
		=function(){
			var storedData=this.storedData;
			if(!storedData){storedData={};}
			var currentEventId=storedData.currentEventId;
			if(!currentEventId){
				currentEventId="default";
			}else{
				currentEventId=String(currentEventId);
			}
			var currentEvents=this.loadedEvents[currentEventId];

			if(!currentEvents){
				currentEventId="default";
			}
			debug("event id:"+currentEventId);
			return currentEventId;
		}

	USWidgetManager.prototype.getBaseZIndex
		=function(){
			return Number(this.baseZIndex);
		}

	USWidgetManager.PROCESS_NAME_NONE="none";
	USWidgetManager.PROCESS_NAME_DRAG="drag";
	USWidgetManager.PROCESS_NAME_SYNCHRONIZE="synchronize";

	var USWidget
		=function(unloadWidget){
			debug("USWidget:start");
			this.processFlag=USWidget.PROCESS_NAME_NONE;
			this.temporaryData={};
			this.storedDatas={};
			this.setNoticeDragStart(function(){});
			this.setNoticeProcessEnd(function(){});
			this.setNoticeChangeStoredDatas(function(){});
			this.setNoticeActivate(function(){});
			this.setGetCurrentEvents(function(){return {};});
			this.loadWidget(unloadWidget);
			debug("USWidget:end");
		}

	USWidget.prototype.loadWidget
		=function(unloadWidget){

			var requiredParameter=["name","id","icon","body"];
//			var allowedParameter=["events","styles","debugFlag"];
			var allowedParameter=["debugFlag"];
			var widget={};
			map(
				requiredParameter,
				function(param){
					if(param in unloadWidget){
						widget[param]=unloadWidget[param];
					}else{
						var errstr="widget object require \""+param+"\".";
						debug(errstr,unloadWidget.debugFlag);
						throw errstr;
					}
				}
			);
			map(
				allowedParameter,
				function(param){
					if(param in unloadWidget){
						widget[param]=unloadWidget[param];
					}
				}
			);

			var USWFrame=document.createElement("div");
			var USWHeader=document.createElement("div");
			var USWBody=document.createElement("div");
			var USWSetting=document.createElement("div");
			var USWName=document.createElement("span");
			var USWNameProtection=document.createElement("div");
			var USWSettingButton=document.createElement("img");
			var USWCloseButton=document.createElement("img");
			var USWDockIcon=document.createElement("div");

			setInnerText(USWName,widget.name);

			USWFrame.appendChild(USWHeader);
			USWFrame.appendChild(USWBody);
			USWFrame.appendChild(USWSetting);
			USWHeader.appendChild(USWName);
			USWHeader.appendChild(USWNameProtection);
			USWHeader.appendChild(USWSettingButton);
			USWHeader.appendChild(USWCloseButton);
			USWBody.appendChild(widget.body);
			USWDockIcon.appendChild(widget.icon);

			this.USWFrame=USWFrame;
			this.USWHeader=USWHeader;
			this.USWBody=USWBody;
			this.USWSetting=USWSetting;
			this.USWName=USWName;
			this.USWNameProtection=USWNameProtection;
			this.USWSettingButton=USWSettingButton;
			this.USWCloseButton=USWCloseButton;
			this.USWDockIcon=USWDockIcon

			this.id=widget.id;

			var USWSelectBasePoint=document.createElement("div");
			var USWSelectBasePointTitle=document.createElement("div");
			var USWSelectBasePointBody=document.createElement("div");
			var USWSelectBasePointTL=document.createElement("img");
			var USWSelectBasePointTR=document.createElement("img");
			var USWSelectBasePointBL=document.createElement("img");
			var USWSelectBasePointBR=document.createElement("img");

			setInnerText(USWSelectBasePointTitle,"Base Point");

			USWSetting.appendChild(USWSelectBasePoint);
			USWSelectBasePoint.appendChild(USWSelectBasePointTitle);
			USWSelectBasePoint.appendChild(USWSelectBasePointBody);
			USWSelectBasePointBody.appendChild(USWSelectBasePointTL);
			USWSelectBasePointBody.appendChild(USWSelectBasePointTR);
			USWSelectBasePointBody.appendChild(USWSelectBasePointBL);
			USWSelectBasePointBody.appendChild(USWSelectBasePointBR);

			this.USWSelectBasePoint=USWSelectBasePoint;
			this.USWSelectBasePointTitle=USWSelectBasePointTitle;
			this.USWSelectBasePointBody=USWSelectBasePointBody;
			this.USWSelectBasePointTL=USWSelectBasePointTL;
			this.USWSelectBasePointTR=USWSelectBasePointTR;
			this.USWSelectBasePointBL=USWSelectBasePointBL;
			this.USWSelectBasePointBR=USWSelectBasePointBR;

			var handler
				=(function(scope){
					var _scope=scope;
					return function(x,y){
						var _x=x;
						var _y=y;
						return function(){
							scope.setStoredDatas({"baseX":_x,"baseY":_y});
							scope.savePositionData();
							scope.redraw();
						}
					}
				})(this);
			this.USWSelectBasePointTL.addEventListener(
				"click",handler(POSITION.X.LEFT,POSITION.Y.TOP),true);
			this.USWSelectBasePointTR.addEventListener(
				"click",handler(POSITION.X.RIGHT,POSITION.Y.TOP),true);
			this.USWSelectBasePointBL.addEventListener(
				"click",handler(POSITION.X.LEFT,POSITION.Y.BOTTOM),true);
			this.USWSelectBasePointBR.addEventListener(
				"click",handler(POSITION.X.RIGHT,POSITION.Y.BOTTOM),true);

		}

	USWidget.prototype.isDragging
		=function(){
			return this.getProcessName()==USWidget.PROCESS_NAME_DRAG;
		}

	USWidget.prototype.getProcessName
		=function(){
			return String(this.processFlag);
		}

	USWidget.prototype.dragStart
		=function(){
			var result=this.noticeDragStart(this);
			if(result){
				this.processFlag=USWidget.PROCESS_NAME_DRAG;
			}
			return result;
		}

	USWidget.prototype.processEnd
		=function(){
			var result=this.noticeProcessEnd(this);
			this.processFlag=USWidget.PROCESS_NAME_NONE;
			return result;
		}

	USWidget.prototype.setNoticeDragStart
		=function(fnc){
			this.noticeDragStart=fnc;
		}

	USWidget.prototype.setNoticeProcessEnd
		=function(fnc){
			this.noticeProcessEnd=fnc;
		}

	USWidget.prototype.setNoticeChangeStoredDatas
		=function(fnc){
			this.noticeChangeStoredDatas=fnc;
		}

	USWidget.prototype.setNoticeActivate
		=function(fnc){
			this.noticeActivate=fnc;
		}

	USWidget.prototype.setGetCurrentEvents
		=function(fnc){
			this.getCurrentEvents=fnc;
		}

	USWidget.prototype.setGetBaseZIndex
		=function(fnc){
			this.getBaseZIndex=fnc;
		}

	USWidget.prototype.activate
		=function(){
			this.noticeActivate(this);
		}

	USWidget.prototype.setStoredDatas
		=function(data){
			var allowedParameter=USWidget.getStoredDataNames();
			var storedDatas=this.storedDatas;
			map(
				allowedParameter,
				function(param){
					if(param in data){
						storedDatas[param]=data[param];
					}
				}
			);
			this.noticeChangeStoredDatas(this);
		}
	USWidget.prototype.getStoredDatas
		=function(){
			var allowedParameter=USWidget.getStoredDataNames();
			var storedDatas=this.storedDatas;
			var rtn={};
			map(
				allowedParameter,
				function(param){
					if(param in storedDatas){
						rtn[param]=storedDatas[param];
					}
				}
			);
			return rtn;
		}

	USWidget.getInitialStoredDatas
		=function(){
			return {
				"baseX":POSITION.X.LEFT,
				"baseY":POSITION.Y.TOP,
				"frameX":0,
				"frameY":0,
				"enable":true,
				"fold":false,
				"setting":false,
				"zIndex":0
			};
		}

	USWidget.getStoredDataNames
		=function(){
			var initialStoredDatas=USWidget.getInitialStoredDatas();
			var ary=[];
			for(var key in initialStoredDatas){
				ary.push(key);
			}
			return ary;
		}

	USWidget.prototype.savePositionData
		=function(){
			var fpos=getDisplayPosition(this.USWFrame);
			var strd=this.getStoredDatas();
			var storedDatas={};
			switch(strd.baseX){
			case POSITION.X.LEFT:storedDatas.frameX=fpos.left;break;
			case POSITION.X.RIGHT:storedDatas.frameX=fpos.right;break;
			}
			switch(strd.baseY){
			case POSITION.Y.TOP:storedDatas.frameY=fpos.top;break;
			case POSITION.Y.BOTTOM:storedDatas.frameY=fpos.bottom;break;
			}
			this.setStoredDatas(storedDatas);
		}

	USWidget.prototype.redraw
		=function(){

			var storedDatas=this.getStoredDatas();
			switch(storedDatas.baseX){
			case POSITION.X.LEFT:
				this.USWFrame.style.left=storedDatas.frameX+"px";
				this.USWFrame.style.right="auto";
				break;
			case POSITION.X.RIGHT:
				this.USWFrame.style.right=storedDatas.frameX+"px";
				this.USWFrame.style.left="auto";
				break;
			}
			switch(storedDatas.baseY){
			case POSITION.Y.TOP:
				this.USWFrame.style.top=storedDatas.frameY+"px";
				this.USWFrame.style.bottom="auto";
				break;
			case POSITION.Y.BOTTOM:
				this.USWFrame.style.bottom=storedDatas.frameY+"px";
				this.USWFrame.style.top="auto";
				break;
			}
			if(storedDatas.enable){
				this.USWFrame.style.display="";
			}else{
				this.USWFrame.style.display="none";
			}
			if(storedDatas.fold){
				this.USWBody.style.visibility="hidden";
				this.USWBody.style.height="0px";
				this.USWSettingButton.style.visibility="hidden";
			}else{
				this.USWBody.style.visibility="visible";
				this.USWBody.style.height="auto";
				this.USWSettingButton.style.visibility="visible";
			}
			if(storedDatas.setting){
				this.USWSetting.style.display="";
				this.USWCloseButton.style.visibility="hidden";
			}else{
				this.USWSetting.style.display="none";
				this.USWCloseButton.style.visibility="visible";
			}
			var frameWidth=this.USWFrame.offsetWidth;
			var settingWidth=this.USWSetting.offsetWidth;
			this.USWSetting.style.left=
				Math.round((frameWidth-settingWidth)/2)+"px"
			this.USWSetting.style.top=
				this.USWHeader.offsetHeight+"px";
			this.USWFrame.style.zIndex=
				String(storedDatas.zIndex+this.getBaseZIndex());
			this.USWSelectBasePointTL.setAttribute("src",IMAGE_URI_RADIO_OFF);
			this.USWSelectBasePointTR.setAttribute("src",IMAGE_URI_RADIO_OFF);
			this.USWSelectBasePointBL.setAttribute("src",IMAGE_URI_RADIO_OFF);
			this.USWSelectBasePointBR.setAttribute("src",IMAGE_URI_RADIO_OFF);
			if(false){
			}else if(storedDatas.baseX==POSITION.X.LEFT&&
					 storedDatas.baseY==POSITION.Y.TOP){
				this.USWSelectBasePointTL.setAttribute("src",IMAGE_URI_RADIO_ON);
			}else if(storedDatas.baseX==POSITION.X.RIGHT&&
					 storedDatas.baseY==POSITION.Y.TOP){
				this.USWSelectBasePointTR.setAttribute("src",IMAGE_URI_RADIO_ON);
			}else if(storedDatas.baseX==POSITION.X.LEFT&&
					 storedDatas.baseY==POSITION.Y.BOTTOM){
				this.USWSelectBasePointBL.setAttribute("src",IMAGE_URI_RADIO_ON);
			}else if(storedDatas.baseX==POSITION.X.RIGHT&&
					 storedDatas.baseY==POSITION.Y.BOTTOM){
				this.USWSelectBasePointBR.setAttribute("src",IMAGE_URI_RADIO_ON);
			}

		}

	USWidget.prototype.addEvent
		=function(){
			var objs=
				["Frame","Header","NameProtection","Body",
				 "SettingButton","CloseButton","DockIcon"];
			var etypes=
				["mouseover","mouseout","mousemove",
				 "mousedown","mouseup",
				 "click","dblclick"];
			var onevent=(function(scope){
				var _scope=scope;
				return function(){_scope.onEvent.apply(_scope,arguments)};
			})(this);
			var oneventForMap=(function(scope){
				var _scope=scope;
				return function(args){
					var obj=args[0];
					var etype=args[1];
					_scope["USW"+obj].addEventListener(
						etype,
						function(e){onevent(e,obj,etype);},
						true
					);
				}
			})(this)
			var cp=getCartesianProduct(objs,etypes);
			map(cp,oneventForMap);
		}

	USWidget.prototype.onEvent
		=function(e,obj,etype){
			debug("USWidget#onEvent:start");
			var currentEventBody=this.getCurrentEvents();
			if(currentEventBody&&
			   currentEventBody[obj]&&
			   currentEventBody[obj][etype]){
				debug("USWidget#onEvent:onevent");
				currentEventBody[obj][etype].call(this,e);
			}
			debug("USWidget#onEvent:end");
		}

	USWidget.prototype.resetStyles
		=function(){

			setInitialStyle(this.USWFrame);
			setInitialStyle(this.USWHeader);
			setInitialStyle(this.USWNameProtection);
			setInitialStyle(this.USWBody);
			setInitialStyle(this.USWSetting);
			setInitialStyle(this.USWName);
			setInitialStyle(this.USWSettingButton);
			setInitialStyle(this.USWCloseButton);
			setInitialStyle(this.USWDockIcon);

			this.USWCloseButton.setAttribute("src",IMAGE_URI_DISPOSE_DOCK);
			this.USWSettingButton.setAttribute("src",IMAGE_URI_OPEN_SETTING);

			this.USWFrame.style.position="fixed";
			this.USWFrame.style.zIndex="";
			this.USWFrame.style.border="solid 1px #000000";
//			this.USWFrame.style.backgroundColor="#ffffff";
			this.USWHeader.style.textAlign="center";
			this.USWHeader.style.backgroundImage="url(\""+IMAGE_URI_TITLE_BACKGROUND+"\")";
			this.USWHeader.style.height="16px";
			this.USWNameProtection.style.position="absolute";
			this.USWNameProtection.style.top="0px";
			this.USWNameProtection.style.right="0px";
			this.USWNameProtection.style.left="0px";
			this.USWNameProtection.style.height="16px";
			this.USWNameProtection.style.opacity="0.5";
			this.USWSetting.style.display="none";
			this.USWSetting.style.position="absolute";
			this.USWSetting.style.border="solid 1px #000000";
			this.USWSetting.style.backgroundColor="#ffffff";
			this.USWSetting.style.opacity="0.9";
			this.USWName.style.display="inline";
			this.USWSettingButton.style.position="absolute";
			this.USWSettingButton.style.top="0px";
			this.USWSettingButton.style.left="0px";
			this.USWCloseButton.style.position="absolute";
			this.USWCloseButton.style.top="0px";
			this.USWCloseButton.style.right="0px";

			setInitialStyle(this.USWSelectBasePoint);
			setInitialStyle(this.USWSelectBasePointTitle);
			setInitialStyle(this.USWSelectBasePointBody);
			setInitialStyle(this.USWSelectBasePointTL);
			setInitialStyle(this.USWSelectBasePointTR);
			setInitialStyle(this.USWSelectBasePointBL);
			setInitialStyle(this.USWSelectBasePointBR);

			this.USWSelectBasePoint.style.padding="5px";
			this.USWSelectBasePointBody.style.position="relative";
			this.USWSelectBasePointBody.style.width="100px";
			this.USWSelectBasePointBody.style.height="100px";
			this.USWSelectBasePointTL.style.position="absolute";
			this.USWSelectBasePointTL.style.top="0px";
			this.USWSelectBasePointTL.style.left="0px";
			this.USWSelectBasePointTR.style.position="absolute";
			this.USWSelectBasePointTR.style.top="0px";
			this.USWSelectBasePointTR.style.right="0px";
			this.USWSelectBasePointBL.style.position="absolute";
			this.USWSelectBasePointBL.style.bottom="0px";
			this.USWSelectBasePointBL.style.left="0px";
			this.USWSelectBasePointBR.style.position="absolute";
			this.USWSelectBasePointBR.style.bottom="0px";
			this.USWSelectBasePointBR.style.right="0px";

		}

	USWidget.PROCESS_NAME_NONE="none";
	USWidget.PROCESS_NAME_DRAG="drag";
	USWidget.PROCESS_NAME_SYNCHRONIZE="synchronize";

	var USWDefaultWidgetEvents={
		name:"default",
		id:"default",
		events:{
			Frame:{
				click:function(e){
					this.activate();
				},
				mousedown:function(e){
					debug("Frame#mousedown:start");
					if(!this.dragStart()){return;}
					debug("Frame#mousedown:start2");
					this.temporaryData.frameDrag={
						mouseX:e.pageX,
						mouseY:e.pageY,
						framePosition:getDisplayPosition(this.USWFrame),
						storedDatas:this.getStoredDatas()
					}
					this.activate();
				},
				mousemove:function(e){
					debug("Frame#mousemove:start");
					if(!this.isDragging()){return;}
					debug("Frame#mousemove:start2");
					var fdrg=this.temporaryData.frameDrag;
					var fpos=fdrg.framePosition;
					var strd=this.getStoredDatas();//fdrg.storedDatas;

					switch(strd.baseX){
					case POSITION.X.LEFT:
						this.USWFrame.style.left=
							(fpos.left+(e.pageX-fdrg.mouseX))+"px";
						this.USWFrame.style.right="auto";
						break;
					case POSITION.X.RIGHT:
						this.USWFrame.style.right=
							(fpos.right-(e.pageX-fdrg.mouseX))+"px";
						this.USWFrame.style.left="auto";
						break;
					}

					switch(strd.baseY){
					case POSITION.Y.TOP:
						this.USWFrame.style.top=
							(fpos.top+(e.pageY-fdrg.mouseY))+"px";
						this.USWFrame.style.bottom="auto";
						break;
					case POSITION.Y.BOTTOM:
						this.USWFrame.style.bottom=
							(fpos.bottom-(e.pageY-fdrg.mouseY))+"px";
						this.USWFrame.style.top="auto";
						break;
					}
				},
				mouseup:function(e){
					debug("Frame#mouseup:start");
					if(!this.isDragging()){return;}
					this.savePositionData();
					this.processEnd();
				},
				mouseover:function(e){
					debug("Frame#mouseover:start");
					if(!this.isDragging()){return;}
					this.savePositionData();
					this.processEnd();
				},
				mouseout:function(e){
					debug("Frame#mouseout:start");
					if(!this.isDragging()){return;}
					this.savePositionData();
					this.processEnd();
				}
			},
			Header:{
				dblclick:function(e){
					debug("Header#dblclick:start");
					var storedDatas=this.getStoredDatas();
					if(storedDatas.setting){return;}
					this.setStoredDatas({fold:!storedDatas.fold});
					this.redraw();
				}
			},
			WidgetWrapper:{},
			CloseButton:{
				click:function(e){
					debug("CloseButton#click:start");
					var storedDatas=this.getStoredDatas();
					if(storedDatas.setting){return;}
					this.setStoredDatas({enable:false});
					this.redraw();
				}
			},
			SettingButton:{
				click:function(e){
					debug("SettingButton#click:start");
					var storedDatas=this.getStoredDatas();
					if(storedDatas.fold){return;}
					this.setStoredDatas({setting:!storedDatas.setting});
					this.redraw();
				}
			},
			DockIcon:{
				click:function(e){
					debug("DockIcon#click:start");
					var storedDatas=this.getStoredDatas();
					this.setStoredDatas({enable:!storedDatas.enable});
					this.activate();
					this.redraw();
				}
			}
		}
	}
////

	var USWDefaultWidgetStyles
		=function(){
//TODO
		}

	var IMAGE_URI_SETTING
		="data:image/gif;base64,"
		+"R0lGODdhEAAQAMIGADMzM2ZmZpmZmcTEzsrKzMzMzP%2F%2F%2F%2F%2F%2F%2Fy"
		+"wAAAAAEAAQAAADQ1i63CowSgnKnCXAemXIAtdlnyVezgkpJaMK7UAsJ7jIAaBba5"
		+"MDgRwPxsgFgxxQC3gUEovMo6hViEqHyyZSx%2B16dQkAOw%3D%3D";

	var USWSetting
		=function(setDockDatas,getDockDatas){

			var icon=document.createElement("img");
			var body=document.createElement("div");
			var position=document.createElement("div");
			var positionTitle=document.createElement("div");
			var positionBody=document.createElement("div");
			var positionIcons=[];

			this.positionIcons=positionIcons;

			this.setDockDatas=setDockDatas;
			this.getDockDatas=getDockDatas;
/*
			this.getDockDatas=function(){
				var dockDatas=getDockDatas();
				var rtn={};
				for(var key in dockDatas){
					rtn[key]=dockDatas[key];
				}
				rtn["x"]=rtn["x"]?rtn["x"]:POSITION.X.LEFT;
				rtn["y"]=rtn["y"]?rtn["y"]:POSITION.Y.TOP;
				return rtn;
			};
*/
			setInnerText(positionTitle,"dock position");

			setInitialStyle(body);
			setInitialStyle(position);
			setInitialStyle(positionTitle);
			setInitialStyle(positionBody);

			icon.setAttribute("src",IMAGE_URI_SETTING);

			body.style.backgroundColor="#ffffff";
			positionBody.style.position="relative";
			positionBody.style.width="100px";
			positionBody.style.height="100px";

			map(
				DOCK_POSITION_COMBINATION,
				function(pos){
					var positionIcon=document.createElement("img");
					setInitialStyle(positionIcon);
					positionIcon.style.position="absolute";
					switch(pos.x){
					case POSITION.X.LEFT:positionIcon.style.left="0px";break;
					case POSITION.X.RIGHT:positionIcon.style.right="0px";break;
					}
					switch(pos.y){
					case POSITION.Y.TOP:positionIcon.style.top="0px";break;
					case POSITION.Y.BOTTOM:positionIcon.style.bottom="0px";break;
					}
					positionBody.appendChild(positionIcon);
					var positionIconData={"element":positionIcon,"x":pos.x,"y":pos.y};
					positionIcons.push(positionIconData);
				}
			);
			var handler=
				(function(scope){
					return function(x,y){
						return function(){
							var dockDatas=scope.getDockDatas();///call?
							dockDatas.x=x;
							dockDatas.y=y;
							scope.setDockDatas(dockDatas);////call?
							scope.redraw();
						}
					}
				})(this);

			this.redraw();

			map(positionIcons,
				function(positionIcon){
					positionIcon.element.addEventListener(
						"click",
						handler(positionIcon.x,positionIcon.y),
						true
					);
				}
			);
			body.appendChild(position);
			position.appendChild(positionTitle);
			position.appendChild(positionBody);
			var usw={
				"icon":icon,
				"body":body,
				"name":"setting",
				"id":"http://www.kanasansoft.com/setting"
			}

			if(!("_USWidgetManager_" in window)){
				window._USWidgetManager_={};
			}
			if(!("widgets" in window._USWidgetManager_)){
				window._USWidgetManager_.widgets=[];
			}
			window._USWidgetManager_.widgets.push(usw);
			if(window._USWidgetManager_.noticeAddWidgets){
				window._USWidgetManager_.noticeAddWidgets();
			}
		}

	USWSetting.prototype.redraw
		=function(){
			var positionIcons=this.positionIcons;
			var dockDatas=this.getDockDatas();
			map(positionIcons,
				function(positionIcon){
					if(positionIcon.x==dockDatas.x&&
					   positionIcon.y==dockDatas.y){
						positionIcon.element.setAttribute("src",IMAGE_URI_RADIO_ON);
					}else{
						positionIcon.element.setAttribute("src",IMAGE_URI_RADIO_OFF);
					}
				}
			);
		}

	var onLoad
		=	function(){
			if(window.self!=window.top){
				return;
			}
			var uswm=new USWidgetManager();
			window._USWidgetManager_.events.push(USWDefaultWidgetEvents);
			window._USWidgetManager_.noticeAddEvents();

			var getDockDatas=closurize(uswm,uswm.getDockDatas);
			var setDockDatas=closurize(uswm,uswm.setDockDatas);

			var test=new USWSetting(
				setDockDatas,
				getDockDatas
			);
		}

	window.addEventListener("load",onLoad,true);

})();
