var g_images_path = "images/";

function gbPoint(x,y)
{
	if(x == undefined){
		this.x = 0;
		this.y = 0;
	}
	else{
		this.x = x;
		this.y = y;
	}
}

gbPoint.prototype.fromXML = function(x)
{
	this.x = x.getAttribute("x");
	this.y = x.getAttribute("y");
}

gbPoint.prototype.toQuery = function()
{
	return this.x+"_"+this.y;
}


function gbPosition(type,x,y,rot,reso)
{
	this.type = type;
	this.center = new gbPoint(x,y);
	if(rot == undefined){
		this.rotate = 0;
	}
	else{
		this.rotate = rot;
	}
	if(reso == undefined){
		this.reso = 100;
	}
	else{
		this.reso = reso;
	}
}

gbPosition.prototype.toQuery = function()
{
	// a-[中心座標x]-[中心座標y]-[回転角(度)]-[レゾリューション]
	return this.type+"_"+this.center.x+"_"+this.center.y+"_"+this.rotate+"_"+this.reso;
}



function gbTarget()
{
	this.coord = 1;
	this.position = null;
}

gbTarget.prototype.initByXML = function(x){
	var type = x.getAttribute("type");
	if(type == null){
		type = "a";
	}
	
	this.position = new gbPosition(
		type,
		parseFloat(x.getAttribute("cx")), 
		parseFloat(x.getAttribute("cy")), 
		parseFloat(x.getAttribute("rotate")), 
		parseFloat(x.getAttribute("reso"))
		);
	
	this.coord = x.getAttribute("coord");
	
}


gbTarget.prototype.updateByParamStr = function(paramStr)
{
	var params = paramStr.split("_");
	this.coord = params[0];
	this.position = new gbPosition(
			params[1],
			parseFloat(params[2]),
			parseFloat(params[3]),
			parseFloat(params[4]),
			parseFloat(params[5])
		);
}


gbTarget.prototype.toQuery = function()
{
	return "" + escape(this.coord) + "_" + this.position.toQuery();
}

function gbObj()
{

}

gbObj.prototype.getApp = function()
{
	if(this.app){
		return this.app;
	}
	return null;
}

function gbCoord(app)
{
	this.visible = true;
	this.owner = null;
	this.id = "";
	this.name = "";
	this.locked = false;
	this.isBase = false;
	this.app = app;
}

gbCoord.prototype = new gbObj();

gbCoord.prototype.initByXML = function(coordXML)
{
	this.visible = coordXML.getAttribute("visible") != "false";
	this.id = coordXML.getAttribute("id");
	this.name = coordXML.getAttribute("name");
	this.locked = (coordXML.getAttribute("locked") == "true");
	this.isBase =  (coordXML.getAttribute("base") == "true");
	this.xml = coordXML;
}

gbCoord.prototype.toQuery = function()
{
	return escape(this.id + "(" + (this.locked?"L":"") + (this.visible?"1":"0") + ")");
}

gbCoord.prototype.getHTML = function()
{
	return "<tr><td><div class='coord_style'>"+this.name+"</div></td></tr>";
}

function gbLayerItem()
{
	this.dispDesc = false;
}

gbLayerItem.prototype = new gbObj();

gbLayerItem.prototype.getVisibleBtnId = function()
{
	return "v"+this.getApp().id+"_"+this.id;
}

gbLayerItem.setVisible = function(obj, v){
	obj.visible = v;
	var btn = getObjectById(obj.getVisibleBtnId());
	if(btn && btn.src){
		btn.src = gbLayerItem.getVisibleImagePath(v);
	}
	return true;
}

gbLayerItem.prototype.setVisible = function(v){
	return gbLayerItem.setVisible(this,v);
}

gbLayerItem.getVisibleImagePath = function(v){
	if(v){
		return  g_images_path + "eye_open.gif"
	}
	else{
		return  g_images_path + "eye_close.gif"
	}
}

function gbLayer(app)
{
	this.coords = null;
	this.visible = true;
	this.name = "";
	this.id = "";
	this.app = app;
}

gbLayer.prototype = new gbLayerItem();

gbLayer.prototype.initByXML = function(layerXML)
{
	this.visible = (layerXML.getAttribute("visible") != "false");
	this.name = layerXML.getAttribute("name");
	this.id = layerXML.getAttribute("id");
	
	var children = layerXML.childNodes;
	var coordCount = 0;
	for(var i=0; i<children.length; ++i){
		if(children[i].nodeType == 1){
			if(children[i].nodeName=="coord"){
				++coordCount;
			}
		}
	}

	var idx = 0;
	this.coords = new Array(coordCount);
	for(var i=0; i<children.length; ++i){
		if(children[i].nodeType == 1){
			if(children[i].nodeName=="coord"){
				this.coords[idx] = new gbCoord();
				this.coords[idx].initByXML(children[i]);
				++idx;
			}
			else if(children[i].nodeName=="desc"){
				this.desc = getChildrenText(children[i]);
			}
		}
	}
	this.xml = layerXML;
}

gbLayer.prototype.toQuery = function()
{
	return escape(this.id) + (this.visible?"[1]":"[0]");
}


gbLayer.prototype.getHTML = function()
{
	return gbGetLayerRowHTML(this);
}

gbLayer.prototype.getCoords = function()
{
	return this.coords;
}

gbLayer.prototype.updateDepth = function(depth){
	this.depth = depth;
}

gbLayer.prototype.getItemById = function(id){
	if(this.id  == id){
		return this;
	}
	return null;
}

gbLayer.prototype.updateByParams = function(params){
	var v=false;
	var i=0;
	for(; i<params.length; ++i){
		if(params[i][0] == this.id){
			v = params[i][1]=="1";
			break;
		}
	}
	this.setVisible(v);
}


function gbLayerGroup(app)
{
	this.init(app);
}

gbLayerGroup.prototype = new gbLayerItem();



gbLayerGroup.prototype.init = function(app)
{
	this.max_layer = 20;
	this.htmlId = "layerGroup";
	this.id = 0;
	this.layers = null;
	this.name = null;
	this.visible = true;
	this.app = app;
	this.expand = true;
}


gbLayerGroup.prototype.initByXML = function(layerGroupXML)
{
	var htmlId = layerGroupXML.getAttribute("htmlId");
	if(htmlId != null){
		this.htmlId = htmlId;
	}
	
	var name = layerGroupXML.getAttribute("name");
	if(name != null){
		this.name = name;
	}
	
	var id = layerGroupXML.getAttribute("id");
	if(id != null){
		this.id = id;
	}
	
	this.visible = layerGroupXML.getAttribute("visible")=="false" ? false : true;
	this.xml = layerGroupXML;
	
	var children = layerGroupXML.childNodes;
	
	this.layers = new Array();
	var leyIndex=0;
	for(var i=0; i<children.length; ++i){
		if(children[i].nodeType == 1){
			var node = children[i];
			var newItem=null;
			switch(node.nodeName){
				case "layer":
					newItem = new gbLayer(this.app);
					break;
				case "layerGroup":
					newItem = new gbLayerGroup(this.app);
					break;
				case "desc":
					this.desc = getChildrenText(node);
					break;
			}
			if(newItem!=null){
				newItem.initByXML(node);
				this.layers[leyIndex++] = newItem;
			}
		}
	}
}


gbLayerGroup.prototype.toQuery = function()
{
	var ret="";
	for(var i=0; i<this.layers.length; ++i){
		ret += this.layers[i].toQuery();
	}
	return ret;
}

gbLayerGroup.prototype.getCoords = function()
{
	var ret = new Array();
	if(this.layers != null){
		for(var i=0; i<this.layers.length; ++i){
			var coords = this.layers[i].getCoords();
			if(coords && coords.length>0){
				ret = ret.concat(coords);
			}
		}
	}
	return ret;
}


gbLayerGroup.prototype.updateByParams = function(params){
	var v = false;
	for(var i=0; i<params.length; ++i){
		if(params[i][0] == this.id){
			v = params[i][1]=="1";
			break;
		}
	}
	this.setVisible(v);
	for(var i=0; i<this.layers.length; ++i){
		this.layers[i].updateByParams(params);
	}
}


function gbSwitchExpand(appid, id){
	var item = gbApp.instances[appid].layerCtrl.getItemById(id);
	if(item != null){
		item.expand = !item.expand;
	}
	gbApp.instances[appid].layerCtrl.update();
}


function gbSwitchVisible(appid, id){
	var app = gbApp.instances[appid];
	var item = app.layerCtrl.getItemById(id);
	if(item != null){
		item.setVisible(!item.visible);
		
		app.updateImage(false);
	}
}

function gbShowDesc(ctrl, appid, id){
	var app = gbApp.instances[appid];
	var item = app.layerCtrl.getItemById(id);
	item.dispDesc = !item.dispDesc;
	app.layerCtrl.update();
}

function gbGetLayerRowHTML(obj)
{

	var begin_cell = "<td class=\""+(obj.xml.nodeName)+"_cell_style\" >";
	
	var ret = "<tr class=\""+(obj.xml.nodeName)+"_row_style\">";
	
	var image_src;
	if(obj.expand!=undefined){
		if(obj.expand){
			image_src = g_images_path + "expand.gif";
		}
		else{
			image_src = g_images_path + "unexpand.gif";
		}
		ret += begin_cell+getClickableImageHTML(image_src, "gbSwitchExpand('"+obj.getApp().id+"','"+obj.id+"')")+"</td>";
	}
	else{
		ret += begin_cell + "</td>";
	}
	
	if(obj.visible){
		image_src = gbLayerItem.getVisibleImagePath(true);
	}
	else{
		image_src = gbLayerItem.getVisibleImagePath(false);
	}
	
	ret += begin_cell+getClickableImageHTML(image_src, "gbSwitchVisible('"+obj.getApp().id+"','"+obj.id+"')", obj.getVisibleBtnId())+"</td>";
	
	ret += begin_cell;
	if(obj.depth){
		for(var i=0; i<obj.depth; ++i){
			ret+="&nbsp;&nbsp;&nbsp;&nbsp;";
		}
	}
	if(obj.desc){
		ret+="<span style=\"cursor:pointer\" onClick=\"gbShowDesc(this,'"+obj.getApp().id+"','"+obj.id+"')\">" + obj.name + "</span>";
		if(obj.dispDesc){
			ret+="<br><span class='desc_style'>"+obj.desc+"</span>";
		}
	}
	else{
		ret+=obj.name;
	}
	ret+="</td>";
	
	
	ret+="<tr>";
	return ret;
}



gbLayerGroup.prototype.getHTML = function()
{
	var ret = gbGetLayerRowHTML(this);
	if(this.layers != null && this.expand){
		for(var i=0; i<this.layers.length; ++i){
			ret += this.layers[i].getHTML();
		}
	}
	return ret;
}

gbLayerGroup.prototype.updateDepth = function(depth){
	this.depth = depth;
	for(var i=0; i<this.layers.length; ++i){
		this.layers[i].updateDepth(depth+1);
	}
}

gbLayerGroup.prototype.setVisible = function(v){
trace("gbLayerGroup.prototype.setVisible called");
	if(!gbLayerItem.setVisible(this, v)){
		return false;
	}
	for(var i=0; i<this.layers.length; ++i){
		if(!this.layers[i].setVisible(v)){
			return false;
		}
	}
	return true;
}

gbLayerGroup.prototype.getItemById = function(id)
{
	if(this.id == id){
		return this;
	}
	for(var i=0; i<this.layers.length; ++i){
		var item = this.layers[i].getItemById(id);
		if(item != null){
			return item;
		}
	}
	return null;
}

function gbLayerCtrl(app)
{
	this.init(app);
}

gbLayerCtrl.prototype = new gbLayerGroup();

gbLayerCtrl.prototype.getHTML = function()
{
	var ret ="<table><tr><th>展開</th><th>表示</th><th style='width:200'>レイヤ名</th></tr>";
	if(this.layers != null){
		for(var i=0; i<this.layers.length; ++i){
			ret += this.layers[i].getHTML();
		}
	}
	ret +="</table>";
	return ret;
}


gbLayerCtrl.prototype.update = function()
{
	var obj = getObjectById(this.htmlId);
	if(obj == null){
		trace("layer control \""+this.htmlId+"\" not found");
		return;
	}
	obj.innerHTML = this.getHTML();
}

gbLayerCtrl.prototype.updateDepth = function(){
	for(var i=0; i<this.layers.length; ++i){
		this.layers[i].updateDepth(0);
	}
}

gbLayerCtrl.prototype.updateByParamStr = function(paramStr){
	var paramStr = unescape(paramStr);
	trace("gbLayerCtrl.prototype.updateByParamStr called paramStr="+paramStr);
	
	var params = paramStr.split("]");
	var _params = new Array(params.length);
	for(var i=0; i<params.length; ++i){
		_params[i] = params[i].split("[");
	}
	
	for(var i=0; i<this.layers.length; ++i){
		this.layers[i].updateByParams(_params);
	}
}

function gbImageStatus(app){
	this.taskCount = 0;
	this.isDirty = true;
	this.crdStatus = "";
	this.resourcePath = "";
	this.resetInterval();
	this.app = app;
	this.timeoutId = -1;
	this.isNeedUpdate = false;
}

gbImageStatus.prototype.cancelNextTimeout = function()
{
	trace("gbImageStatus.prototype.cancelNextTimeout called this.timeoutId="+this.timeoutId);
	if(this.timeoutId != -1){
		window.clearInterval(this.timeoutId);
		this.timeoutId = -1;
	}
}

gbImageStatus.prototype.beginNextUpdateTimer = function()
{
	if(this.isNeedUpdate){
		this.cancelNextTimeout();
		var app = this.app;
		var stat = this;
		this.timeoutId = window.setInterval(
			function(){window.clearInterval(stat.timeoutId); trace("beginNextUpdateTimer onTimer."); app.updateImage(false);}, 
			this.getNextInterval());
	}
}

gbImageStatus.prototype.resetInterval = function()
{
	this.nextInterval = 100;
}

gbImageStatus.prototype.setNextStatus = function(resourcePath, taskCount, isDirty, crdStatus)
{
	this.cancelNextTimeout();
	if(!this.isDirty && !isDirty && (taskCount==0)){
		this.isNeedUpdate = false;
	}
	else{
		this.isNeedUpdate = true;
		if(!this.isDirty && !isDirty){
			if(this.nextInterval<10000){
				this.nextInterval *= 2;
				if(this.nextInterval>10000){
					this.nextInterval = 10000;
				}
			}
		}
		else{
			this.resetInterval();
		}
	}
	
	this.resourcePath = resourcePath;
	this.taskCount = taskCount;
	this.isDirty = isDirty;
	this.crdStatus = crdStatus;
}

gbImageStatus.prototype.getNextInterval = function()
{
	return this.nextInterval;
}

function gbXPanel(app)
{
	trace("gbXPanel() created");
	this.app = app;
	this.htmlId = "gbXPanel";
	this.keys = new Array(9);
	for(var i=0; i<9; ++i){
		this.keys[i] = {idx:i, down:new Image(), up:new Image(), state:'up', ctrl:null};
		if(i!=4){
			this.keys[i].up.src = g_images_path+"ct_btn_"+i+"u.gif";
			this.keys[i].down.src = g_images_path+"ct_btn_"+i+"d.gif";
		}
		this.keys[i].dx = -(app.imageWidth/2) * (i%3 - 1);
		this.keys[i].dy = -(app.imageHeight/2) * (Math.floor(i/3) - 1);
	}
}

gbXPanel.prototype.initByXML = function(x)
{
	var id = x.getAttribute("htmlId");
	if(id!= null){
		this.htmlId = id;
	}
	this.ctrl = getObjectById(this.htmlId);
	this.ctrl.style.zIndex = 100;
	this.ctrl.innerHTML = this.getHTML();
}

gbXPanel.prototype.getHTML = function()
{
	var ret="<table>";
	for(var i=0; i<3; ++i){
		ret+="<tr>";
		for(var j=0; j<3; ++j){
			ret+="<td style='padding:0'>";
			if(!(i==1&&j==1)){
				var key = this.keys[i*3+j];
				
				ret+="<image id='"+this.getKeyId(i*3+j)+"' src='"+key[key.state].src+"'";
			}
			ret+="</td>";
		}
		ret+="</tr>";
	}
	ret+="</table>";
	return ret;
}

gbXPanel.prototype.getKeyId = function(i)
{
	return this.htmlId+"key"+i;
}

gbXPanel.prototype.initKeyCtrl = function()
{
	if(this.keys[0].ctrl != null){
		return;
	}
	for(var i=0;i<9;++i){
		this.keys[i].ctrl = getObjectById(this.getKeyId(i));
	}
}

gbXPanel.prototype.isContains = function(obj)
{
	this.initKeyCtrl();
	
	for(var i=0;i<9;++i){
		if(this.keys[i].ctrl == obj){
			return true;
		}
	}
	return false;
}

gbXPanel.prototype.onMouseDown = function(obj)
{
	this.initKeyCtrl();
	var key = null;
	for(var i=0;i<9;++i){
		if(this.keys[i].ctrl == obj){
			key = this.keys[i];
		}
	}
	
	if(key == null){
		return;
	}
	
	this.onKeyDown(key);
}

gbXPanel.prototype.onMouseUp = function()
{

}

gbXPanel.prototype.onKeyDown = function(key)
{
	if(this.app.moveImageTo(key.dx, key.dy, key)){
		key.ctrl.src = key.down.src;
	}
}


function gbApp(){
	this.confXML = null;
	this.target = null;
	this.layerCtrl = null;
	this.move= new gbPoint(0,0);
	this.zoom=1;
	this.rotate=0;
	this.imageName = "image";
	this.loadingStatus = null;
	this.imageLoader = null;
	this.imageObj = null;
	this.imageAnimQueue = new Array();
	this.mode = "rss";
	this.popupObj = null;
	this.statusCtrl = null;
	this.exParams = null;
	this.oldImageObj = null;
	this.onIdleOperation = null;
	this.isWaitUpdate = false;
	this.currentRequest = null;
	this.clickableMaps = null; // active clickable map 
	this.newClickableMaps = null; // next clickable map 
	this.infoTargetWindow = "gbinfo";
	
	this.abortLevel = gbApp.ABORT_ALL;
	if(gbApp.instances == null){
		gbApp.instances = new Array();
	}
	gbApp.instances.push(this);
	this.id = gbApp.instances.length-1;
}

gbApp.ABORT_NONE = 0;
gbApp.ABORT_IMAGE = 1;
gbApp.ABORT_ALL = 2;


gbApp.prototype.onFinishImageAnim = function(arg)
{
	var k = this.imageAnimQueue[0].hilightKey;
	if(k){
		k.ctrl.src = k.up.src;
	}
	
	if(this.imageAnimQueue.length == 1){
		if((this.imageLoader!=null) && this.imageLoader.isComplete()){
			trace("applyLoadedImage BY onFinishImageAnim");
			this.applyLoadedImage();
		}
		this.imageAnimQueue[0].stop();
	}
	else{
		this.imageAnimQueue[0].destroy();
		delete this.imageAnimQueue[0];
		this.imageAnimQueue.shift();
		this.imageAnimQueue[0].start();
	}
}

gbApp.prototype.setOnIdleOperation = function(eventObj)
{
	this.onIdleOperation = eventObj;
}

gbApp.prototype.moveImageTo_ = function(args)
{
	this.moveImageTo(args[0],args[1],args[2]);
}

gbApp.prototype.getNewAnim = function()
{
	var anim;
	if(this.imageAnimQueue.length==0 || this.imageAnimQueue[0].isActive){
		anim = new divAnim();
		this.imageAnimQueue.push(anim);
	}
	else{
		anim = this.imageAnimQueue[0];
	}
	return anim;
}

gbApp.prototype.moveImageTo = function(xoffset, yoffset, hilight_key)
{
	this.move.x -= xoffset/this.zoom;
	this.move.y -= yoffset/this.zoom;
	
	this.updateImage(true);
	
	
	xdest = -this.move.x*this.zoom+(this.imageWidth-this.imageWidth*this.zoom)/2;
	ydest = -this.move.y*this.zoom+(this.imageHeight-this.imageHeight*this.zoom)/2;
	
	trace("gbApp.prototype.moveImageTo this.imageObj="+this.imageObj);
	
	var anim = this.getNewAnim();
	anim.init(this.imageObj, xdest, ydest, 1, 2*Math.sqrt(xoffset*xoffset+yoffset*yoffset), {obj:this, method:"onFinishImageAnim", args:""});
	anim.hilightKey = hilight_key;
	
	this.kickImageAnim();
	
	return true;
}


function gbGlobalMouseDownHandler(e)
{
	e = (e) ? e : event;
	var obj = e.target ? e.target : e.srcElement;
	if(!gbApp.instances)
		return;
	for(var i=0; i<gbApp.instances.length; ++i){
		gbApp.instances[i].onMouseDown(e,obj);
	}
}

function gbGlobalMouseUpHandler(e)
{
	e = (e) ? e : event;
	var obj = e.target ? e.target : e.srcElement;
	if(!gbApp.instances)
		return;
	for(var i=0; i<gbApp.instances.length; ++i){
		gbApp.instances[i].onMouseUp(e,obj);
	}
}

function gbGlobalMouseMoveHandler(e)
{
	e = (e) ? e : event;
	var obj = e.target ? e.target : e.srcElement;
	
	if(!gbApp.instances)
		return;
	for(var i=0; i<gbApp.instances.length; ++i){
		gbApp.instances[i].onMouseMove(e,obj);
	}
}

gbApp.prototype.applyImageSizeToHtml = function(){
	this.imageObj.style.width = this.imageWidth;
	this.imageObj.style.height = this.imageHeight;
}

gbApp.prototype.initByXML = function(x)
{
	this.confXML = x;

trace("gbApp.prototype.initByXML x.documentElement.childNodes.length="+x.documentElement.childNodes.length);
	if(x.documentElement == null){
		trace("initByXML: load xml error");
	}
	
	var elements = x.documentElement.childNodes;
	
	for(var i=0; i<elements.length; ++i){
		switch(elements[i].nodeName){
			case "image":
				{
					var img = elements[i];
					var htmlId = img.getAttribute("htmlId");
					if(htmlId != null){
						this.imageName = htmlId;
					}
					this.imageWidth = parseInt(img.getAttribute("width"));
					this.imageHeight = parseInt(img.getAttribute("height"));
					this.imageObj = getObjectById(this.imageName);
					this.applyImageSizeToHtml();
					
					var t = img.getAttribute("infoTargetWindow");
					if(t){
						this.infoTargetWindow = t;
					}
				}
				break;
				
			case "layerCtrl":
				this.layerCtrl = new gbLayerCtrl(this);
				this.layerCtrl.initByXML(elements[i]);
				this.layerCtrl.updateDepth();
				break;
			
			case "popup":
				this.popupObj = getObjectById(elements[i].getAttribute("htmlId"));
				break;
			case "xpanel":
				this.xpanel = new gbXPanel(this);
				this.xpanel.initByXML(elements[i]);
				break;
			case "status":
				this.statusCtrl = getObjectById(elements[i].getAttribute("htmlId"));
				break;
				
			case "target":
				this.target = new gbTarget();
				this.target.initByXML(elements[i]);
				break;
				
			default:
		}
	}
}

gbApp.prototype.getQuery = function(mode){
	var ret = new Object();
	if(this.target==null){
		this.target = new gbTarget();
	}
	var target = this.target.toQuery();
	
	var move = this.move.toQuery();
	
	var layer = this.layerCtrl.toQuery();
	var coords = this.layerCtrl.getCoords();
	var coord="";
	for(var i=0; i<coords.length; ++i){
		if(coord != ""){
			coord += "_";
		}
		coord += coords[i].toQuery();
	}
	trace("target query="+target);
	trace("move="+move);
	trace("coord="+coord);
	trace("layer="+layer);
	
	if(this.exParams!=null){
		for(var p in this.exParams){
			ret[p] = this.exParams[p];
		}
	}
	
	ret.p = "0";
	
	ret.t = target;
	ret.mv = move;
	if(this.rotate != 0){
		ret.r = this.rotate;
	}
	ret.z = this.zoom;
	ret.l = layer;
	if(coord!=""){
		ret.c = coord;
	}
	ret.md = mode;
	ret.s = this.imageWidth + "_" + this.imageHeight;
	
	var debug_on = getObjectById("debug_on");
	if(debug_on && debug_on.checked){
		var host = getObjectById("debug_gbhost");
		ret.host = host.value;
		var port = getObjectById("debug_gbport");
		ret.port = port.value;
		var path = getObjectById("debug_gbpath");
		ret.path = path.value;
	}
	
	return object2queryString(ret);
}

gbApp.prototype.clearOldImage = function()
{
	if(this.oldImageObj!=null){
		this.getImageWrap().removeChild(this.oldImageObj);
		delete this.oldImageObj;
		this.oldImageObj = null;
	}
}

gbApp.prototype.applyLoadedImage = function()
{
	
	trace("applyLoadedImage called this.newImageObj="+this.newImageObj);
	
	this.clearOldImage();
	this.oldImageObj = this.imageObj;
	this.imageObj = this.newImageObj;
	this.imageObj.style.left = 0;
	this.imageObj.style.top = 0;
	
	this.clickableMaps = this.newClickableMaps;

	this.setNewParams(this.imageLoader.queryParams);
	
	if(this.onIdleOperation){
		this.onIdleOperation.obj[this.onIdleOperation.method](this.onIdleOperation.args);
		this.onIdleOperation = null;
	}
	else if(this.isWaitUpdate){
		trace("gbApp.prototype.applyLoadedImage this.isWaitUpdate == true");
		this.updateImage(true);
	}
	else{
		this.imageLoader.imageStatus.beginNextUpdateTimer();
		this.imageLoader.setStatus(gbImageLoader.IDLE);
	}
}

gbApp.prototype.setStatusMsg = function(msg)
{
	if(this.statusCtrl){
		this.statusCtrl.innerHTML = msg;
	}
}

gbApp.prototype.onLoadImage = function()
{
trace("onLoadImage called");
	
	this.newImageObj = this.imageLoader.img;
	this.newClickableMaps = this.imageLoader.clickableMaps;
	
	if(this.imageAnimQueue.length == 0 || !this.imageAnimQueue[0].isActive){
		this.applyLoadedImage();
	}
}

gbApp.prototype.getZoom = function(){
	return this.zoom;
}

gbApp.prototype.kickImageAnim = function(){
	if(!this.imageAnimQueue[0].isActive){
		this.imageAnimQueue[0].start();
	}
}

gbApp.prototype.setZoom = function(mag)
{
	var animTime=800;
	
	this.zoom = this.zoom*mag;
	this.updateImage(true);
	
	var anim = this.getNewAnim();
	
	var newWidth = this.imageWidth * this.zoom;
	var x = (this.imageWidth - newWidth)/2 - this.move.x*this.zoom;
	var newHeight = this.imageHeight * this.zoom;
	var y = (this.imageHeight - newHeight)/2 - this.move.y*this.zoom;
	
	anim.init(this.imageObj, x, y, mag, animTime, {obj:this, method:"onFinishImageAnim", args:""});
	this.kickImageAnim();
}

gbApp.prototype.getImageWrap = function()
{
	return getObjectById(this.imageName + "Wrap");
}


gbApp.prototype.getCursorPosOnImage = function()
{
	var wrap = this.getImageWrap();
	var offsetx = this.cursorPos.x - wrap.offsetLeft + getScrollX();
	var offsety = this.cursorPos.y - wrap.offsetTop + getScrollY();
	return {x:offsetx, y:offsety};
}

gbApp.prototype.onMouseDown = function(e, obj)
{
	var wrap = this.getImageWrap();
	trace("gbApp.prototype.onMouseDown obj="+obj+" this.imageObj="+this.imageObj);
	
	if(this.imageObj == obj || this.oldImageObj == obj || obj == wrap){
		this.onMouseDownImage();
	}
	else if(this.xpanel && this.xpanel.isContains(obj)){
		this.xpanel.onMouseDown(obj);
	}
}

gbApp.prototype.onMouseUp = function(e, obj)
{
	this.xpanel.onMouseUp(obj);
}

gbApp.prototype.onMouseMove = function(e, obj)
{
	this.cursorPos = {x:e.clientX, y:e.clientY};
	var wrap = this.getImageWrap();
	
	if(this.imageObj == obj || this.oldImageObj == obj || obj == wrap){
		this.onMouseMoveImage();
	}
}

gbApp.prototype.onMouseMoveImage = function()
{
	var pos = this.getCursorPosOnImage();
	var cursor="default";
	switch(this.mode){
		case 'rss':
		case 'move':
			cursor = "move";
		break;
		
		case 'info':
		case 'info2':
			{
				if(this.clickableMaps){
					var map = this.clickableMaps.hitTest(pos.x, pos.y);
					if(map){
						cursor = "pointer";
					}
					else{
						cursor = "default";
					}
				}
			}
		break;
	}
	this.imageObj.style.cursor = cursor;
	var w = this.getImageWrap();
	w.style.cursor = cursor;
}

gbApp.prototype.onMouseDownImage = function()
{
trace("gbApp.prototype.onMouseDownImage called");

	if(this.imageAnimQueue.length >=1 && this.imageAnimQueue[0].isActive){
		//cancel mouse operation while animate
		return;
	}
	var pos = this.getCursorPosOnImage();
	trace("onMouseDownImage pos.x="+pos.x+" pos.y="+pos.y);
	
	if(this.mode == 'move' || this.mode == 'rss'){
		var destOffsetLeft = this.imageWidth/2 - pos.x;
		var destOffsetTop = this.imageHeight/2 - pos.y;
		this.moveImageTo(destOffsetLeft, destOffsetTop);
	}
	else if(this.mode=='info' || this.mode=='info2'){
		if(this.clickableMaps){
			var map = this.clickableMaps.hitTest(pos.x, pos.y);
			if(map){
				var win = window.open(map.href, this.infoTargetWindow);
				var app = this;
				this.focusInfoInterval = window.setInterval(function(){win.focus();clearInterval(app.focusInfoInterval)},10);
			}
		}
	}
}

gbApp.prototype.onLoadInfo = function(is_success, req, userArg)
{
	trace("onLoadInfo responseText="+req.responseText);
	
	if(!is_success){
		trace("load info error.");
		return;
	}
}

gbApp.prototype.infoRequest = function()
{
	var query = this.getQuery('info2');
	trace("gbgate.cgi?"+query);
	var req = doRequest("gbgate.cgi?"+query, false);
	if(isResponseOK(req)){
		showPopup(req.responseText, this.popupObj);
	}
	else{
		trace("infoRequest error.");
	}
}

gbApp.prototype.updateImage = function(isAbortCurrent){
	trace("gbApp.prototype.updateImage called isAbortCurrent="+isAbortCurrent);
	var oldImageStatus=null;
	
	if(this.imageLoader != null && this.imageLoader.isActive()){
		if(isAbortCurrent){
			trace("gbApp.prototype.updateImage last updateImage was aborted");
			oldImageStatus = this.imageLoader.imageStatus;
			this.imageLoader.abort();
			delete this.imageLoader;
			this.imageLoader = null;
		}
		else{
			trace("updateImage called while updating");
			this.isWaitUpdate = true;
			return;
		}
	}
	else{
		this.clearOldImage();
		if(this.imageLoader){
			oldImageStatus = this.imageLoader.imageStatus;
		}
	}
	this.isWaitUpdate = false;
	
	this.imageLoader = new gbImageLoader(this, this.getQuery('rss'), oldImageStatus);
	
	var app = this;
	this.imageLoader.onStatusMsg = function(msg){
		app.setStatusMsg(msg);
	}
	this.imageLoader.onBeginLoadImage = function(img){
		img.className = "image_style";
		app.imageObj.style.zIndex = 1;
		img.style.zIndex = 2;
		img.style.left = -app.imageWidth;
		app.getImageWrap().appendChild(img);
	}
	this.imageLoader.onCompleteLoadImage = function(img){
trace("this.imageLoader.onCompleteLoadImage called");
		app.onLoadImage();
	}
	this.imageLoader.onAbortLoadImage = function(img){
		trace("onAbortLoadImage this.state="+this.state + " img="+img);
		if(img){
			app.getImageWrap().removeChild(img);
		}
	}
	this.imageLoader.start();

}





gbApp.prototype.setMode = function(mode)
{
	this.mode = mode;
}

gbApp.prototype.setNewParams = function(params)
{
	this.move.x = 0;
	this.move.y = 0;
	this.rotate = 0;
	this.zoom = 1;
	
	if(this.exParams!=null){
		delete this.exParams;
		this.exParams = null;
	}
	this.exParams = new Object();
	
	trace("gbApp.prototype.setNewParams params.length="+params.length);
	for(var i=0; i<params.length; ++i){
		var param = params[i];
		trace("param[0]="+param[0]+ " param[1]="+param[1]);
		switch(param[0]){
			case 'z':
				this.zoom = parseInt(param[1]);
				break;
			case 's':
				{
					var size = param[1].split('_');
					this.imageWidth = parseInt(size[0]);
					this.imageHeight = parseInt(size[1]);
					this.applyImageSizeToHtml();
				}
				break;
			case 't':
				this.target.updateByParamStr(param[1]);
				break;
			case 'l':
// don't update layer visible by server response
//				this.layerCtrl.updateByParamStr(param[1]);
				break;
			default:
				this.exParams[param[0]] = param[1];
				break;
		}
	}
	return params;
}


gbApp.prototype.initByAccessParam = function(paramStr){
	if(paramStr==null || paramStr==""){
		return;
	}
	
	var isLayerSettingExists=false;
	var params = paramStr.split('&');
	for(var i=0;i<params.length; ++i){
		params[i] = params[i].split('=');
		switch(params[i][0]){
			case "l":
				this.layerCtrl.updateByParamStr(params[i][1]);
				isLayerSettingExists=true;
			break;
		}
	}
	
	if(!isLayerSettingExists){
		this.layerCtrl.updateByParamStr("");
	}
	
	this.setNewParams(params);
}

function gbImageLoader(app, query, imageStatus){
	this.app = app;
	this.query = query;
	this.state = gbImageLoader.IDLE;
	if(imageStatus){
		this.imageStatus = imageStatus;
	}
	else{
		this.imageStatus = new gbImageStatus(app);
	}
	this.iamgeWidth = 100;
	this.iamgeHeight = 100;
	this.img = null;
	this.reqObj = null;
	this.imageQueryStr = null;
	this.queryParams = null;
	
	this.clickableMaps = null;
}

gbImageLoader.IDLE = "待機";
gbImageLoader.LOADING_RSS = "RSS取得中";
gbImageLoader.LOADED_RSS = "RSS取得完了";
gbImageLoader.LOADERR_RSS = "RSS取得失敗";
gbImageLoader.LOADING_IMAGE = "画像取得中";
gbImageLoader.LOADED_IMAGE = "画像取得完了";

gbImageLoader.prototype.setQuery = function(query)
{
	this.query = query;
}

gbImageLoader.prototype.isActive = function()
{
	if(this.state == gbImageLoader.IDLE){
		return false;
	}
	return true;
}

gbImageLoader.prototype.start = function()
{
	this.setStatus(gbImageLoader.LOADING_RSS);
trace("get rss request gbgate.cgi?"+this.query);
	this.reqObj = doAsyncRequest("gbgate.cgi?"+this.query, {obj:this, method:"onLoadRSS", args:""});
}

gbImageLoader.prototype.setStatus = function(state){
	this.state = state;
	this.onStatusMsg(state);
}

// for over ride by client program
gbImageLoader.prototype.onStatusMsg = function(msg){
	
}

gbImageLoader.prototype.onLoadRSS = function(is_success, req, userArg)
{
	if(!is_success){
		this.setStatus(gbImageLoader.LOADERR_RSS);
		trace("load rss aborted or error. readyState="+req.readyState+" status="+req.status);
		return;
	}
	if(req.readyState != 4){
		trace("onLoadRSS called by aborted request");
		// aborted response
		return;
	}
	
	trace("gbImageLoader.onLoadRSS responseText.length="+req.responseText.length);
	trace("RESPONSE RSS FILE ="+req.responseText);
	
	var x = req.responseXML;
	if(x.parsed!=undefined && x.parsed==false){
		trace("### wait xml parsed ");
		var loader = this;
		var timeoutid;
		timeoutid = window.setTimeout(function(){loader.onLoadRSS(is_success, req, userArg); window.clearTimeout(timeoutid);}, 0);
		return;
	}
	
	this.setStatus(gbImageLoader.LOADED_RSS);
	
	var images = getElementsByTagName_alt(x, "rdf:li", "li");
	trace("images.length="+images.length);
	if(images.length == 0){
		alert("rdf:li not found in server response rss.");
		return;
	}
	
	var resource = images[0].getAttribute("rdf:resource");
	
	trace("resource="+resource);
	var items = x.getElementsByTagName("item");
	
	for(var i=0; i<items.length; ++i){
		var rdfAbout = items[i].getAttribute("rdf:about");
		if(rdfAbout == resource){
			
//			var link = items[i].getElementsByTagName("link");
//			resource = getChildrenText(link[0]);
			
			var stat1 = getElementsByTagName_alt(items[i], "gb:status1", "status1");
			
			var taskCount = Number(getChildrenText(stat1[0]));
			
			var stat2 = getElementsByTagName_alt(items[i], "gb:status2", "status2");
			var isDirty = (Number(getChildrenText(stat2[0])) == 1);
			
			var stat3 = getElementsByTagName_alt(items[i], "gb:status3", "status3");
			var crdStatus="";
			if(stat3.length!=0){
				crdStatus = getChildrenText(stat3[0]);
			}
			
			var map_xml = getElementsByTagName_alt(items[i], "gb:html-map", "html-map");
			if(map_xml.length!=0){
				this.clickableMaps = new gbClickableMaps();
				this.clickableMaps.initByXML(map_xml[0]);
			}
			
			trace("taskCount="+taskCount+ " crdStatus="+crdStatus+ " isDirty="+isDirty);
			this.imageStatus.setNextStatus(resource, taskCount, isDirty, crdStatus);
			
			break;
		}
	}
	
	var pos = resource.indexOf("?");
	this.imageQueryStr="";
	if(pos != -1){
		this.imageQueryStr = resource.substring(resource.indexOf("?")+1);
	}
	
	var params = this.imageQueryStr.split("&");
	for(var i=0; i<params.length; ++i){
		params[i] = params[i].split("=");
		var param = params[i];
		switch(param[0]){
			case 't':
				this.target = new gbTarget();
				this.target.updateByParamStr(param[1]);
				break;
			case 's':
				var size = param[1].split('_');
				this.iamgeWidth = parseInt(size[0]);
				this.iamgeHeight = parseInt(size[1]);
				break;
		}
	}
	this.queryParams = params;
	
	var is_complete_forced=false;
	if(this.imageStatus.isDirty==false && this.imageStatus.taskCount==0){
		// force complete image
		resource +="&p=1";
		is_complete_forced=true;
	}
	else if(params!=null && params["p"]==1){
		is_complete_forced=true;
	}
	
	if(!is_complete_forced){
		// for no cache
		if(pos==-1){
			resource += "?n="+(new Date()).getTime();
		}else{
			resource += "&n="+(new Date()).getTime();
		}
	}
	
	
	this.img = document.createElement("img");
	this.img.src = resource;
	this.img.style.width = this.iamgeWidth;
	this.img.style.height = this.iamgeHeight;
	
	this.onBeginLoadImage(this.img);
	
	trace("gbImageLoader this.img.complete="+this.img.complete);
	
	var loader = this;
	if(this.img.complete){
		trace("**** resouce:"+resource+" was cached. ****");
		this.setStatus(gbImageLoader.LOADED_IMAGE);
		this.onCompleteLoadImage(this.img);
	}
	else{
		trace("**** resouce:"+resource+" was NOT cached. ****");
		this.setStatus(gbImageLoader.LOADING_IMAGE);
		this.img.onload = function(){
			trace("this.img.onload called loader.img="+loader.img);
			if(loader.img!=null){
				loader.setStatus(gbImageLoader.LOADED_IMAGE);
				loader.onCompleteLoadImage(this);
			}
		}
	}
}

/*private*/
gbImageLoader.prototype.clearReqObj = function()
{
	delete this.reqObj;
	this.reqObj = null;
}

gbImageLoader.prototype.abort = function()
{
	if(this.reqObj!=null){
		this.reqObj.abort();
		this.clearReqObj();
	}
	
	trace("gbImageLoader.prototype.abort called");
	
	if(this.state != gbImageLoader.LOADED_IMAGE){
		this.onAbortLoadImage(this.img);
	trace("gbImageLoader.prototype.abort called 2");
		if(this.img != null){
			this.img.onload = null;
			delete this.img;
			this.img = null;
		}
	}
	
	trace("gbImageLoader.prototype.abort exit this.img="+this.img);
}

gbImageLoader.prototype.isComplete = function()
{
	if(this.img == null){
		return false;
	}
	return this.img.complete;
}


function gbClickableMaps()
{
	this.maps = new Array();
}

gbClickableMaps.prototype.hitTest = function(x,y){
	for(var i=0; i<this.maps.length; ++i){
		if(this.maps[i].left <= x && x <= this.maps[i].right && 
			this.maps[i].top <= y && y <= this.maps[i].bottom){
			return this.maps[i];
		}
	}
	return null;
}

gbClickableMaps.prototype.initByXML = function(x)
{
	for(var n=x.firstChild; n!=null; n=n.nextSibling){
		if(n.nodeName == "area"){
			var name = n.getAttribute("name");
			var shape = n.getAttribute("shape");
			var coords = n.getAttribute("coords");
			var url = n.getAttribute("href");
			if(shape != "rect"){
				alert("click map not support shape="+shape);
			}
			var coords_ = coords.split(",");
			var l = parseInt(coords_[0]);
			var t = parseInt(coords_[1]);
			var r = parseInt(coords_[2]);
			var b = parseInt(coords_[3]);
			
			this.maps.push({left:l, top:t, right:r, bottom:b, href:url});
		}
	}
}

gbClickableMaps.prototype.setParent = function(node)
{
	for(var i=0; i<this.maps.length; ++i){
		node.appendChild(this.maps[i]);
	}
}


function gbCreateApp(confFile, accessParam)
{
	var app = new gbApp();
	app.initByXML(doGetXML(confFile));
	app.initByAccessParam(accessParam);
	app.layerCtrl.update();
	return app;
}


function gbGlobalInit()
{
	if(document.addEventListener){
		document.addEventListener("mousedown", gbGlobalMouseDownHandler, true);
		document.addEventListener("mouseup", gbGlobalMouseUpHandler, true);
		document.addEventListener("mousemove", gbGlobalMouseMoveHandler, true);
	}
	else{
		document.onmousedown = gbGlobalMouseDownHandler;
		document.onmouseup = gbGlobalMouseUpHandler;
		document.onmousemove = gbGlobalMouseMoveHandler;
	}
}

gbGlobalInit();