var Map = Class.create()
Map.prototype = {
  initialize: function(preSetting) {

	if(preSetting.Pin.x){
		var Pins = {x:preSetting.Pin.x, y:preSetting.Pin.y};
		var startPushPin = function(pin){
			this.PushPin(pin);
		}.bind(this);
	}else{
		var Pins = preSetting.Pin;
		var startPushPin = function(pins){
			this.pushPinList(pins);
		}.bind(this);
	}

	//this.root = (location.href.match(/hightube.jp/)) ? '/botanical-garden/resources/' : '/resources/';
	this.root = '/resources/';
	var Setting = {
		Map: {x: 2000, y: 1744},
		View: {x:preSetting.View.x, y:preSetting.View.y},
		Pin: Pins,
		resources: this.root + 'images/',
		map_resources: this.root + 'maps/',
		real_map_resources: this.root + 'real_maps/'
	};

	this.zoom = 0;
	this.zoomSizes = [ [Setting.Map.x, Setting.Map.y], [Setting.Map.x / 2, Setting.Map.y / 2]];

	this.viewportWidth = Setting.View.x;
	this.viewportHight = Setting.View.y;
	this.tileSize = 100;
	this.resources = Setting.resources;
	this.map_resources = Setting.map_resources;

	this.dragging = false;
	this.top;
	this.left;
	this.dragStartTop;
	this.dragStartLeft;

	this.outerDiv = $('outerDiv');
	this.innerDiv = $('innerDiv');
	this.Setting = Setting;

	new OpacityObject('toggleZoomDiv', this.resources + 'zoom').setBackground();
	new OpacityObject('all_listDiv', this.resources + 'all_list').setBackground();
	//new OpacityObject('centerPointDiv', this.resources + 'center').setBackground();

	$('centerPointDiv').style.left = this.viewportWidth/2 + 5.5 + 'px';
	$('centerPointDiv').style.top = this.viewportHight/2 + 5.5 + 'px';


	//startPushPin(Setting.Pin);

  },
  create: function() {
	this.setInnerDivSize(this.zoomSizes[this.zoom][0], this.zoomSizes[this.zoom][1]);

	var outerStyle = this.outerDiv;
	outerStyle.style.width = this.viewportWidth + 'px';
	outerStyle.style.height = this.viewportHight + 'px';

	outerStyle.onmousedown = this.startMove.bind(this);
	outerStyle.onmousemove = this.processMove.bind(this);
	outerStyle.onmouseup = this.stopMove.bind(this);
	//outerStyle.ondblclick = this.clickZoom.bind(this);
	outerStyle.ondragstart = function() { return false; }
	
	$('toggleZoomDiv').onclick = this.toggleZoom.bind(this);
	$('all_listDiv').onclick = function(){
		//var host = (location.href.match(/hightube.jp/)) ? 'http://' + location.host + '/botanical-garden' : 'http://' + location.host;
		var host = 'http://' + location.host;
		location.href = host + '/medias/map'; 
	};
	$('toggleMapTypeDiv').onclick = this.toggleMapType.bind(this);

	//this.checkTiles();
  },
	startMove: function(event) {
		if (!event) event = window.event;
		
		this.dragStartTop = event.clientY;
		this.dragStartLeft = event.clientX;

		//innerDiv.cursor = '-moz-grab';
		this.innerDiv.style.cursor = 'url(' + this.root + '/closedhand.cur.ico), move';

		this.top = this.innerDiv.style.top.stripPx();
		this.left = this.innerDiv.style.left.stripPx();

		this.dragging = true;
		return false;
	},
	processMove: function(event) {
		if (!event) event = window.event;
		if (this.dragging) {
			this.innerDiv.style.top = this.top + (event.clientY - this.dragStartTop) + 'px';
			this.innerDiv.style.left = this.left + (event.clientX - this.dragStartLeft) + 'px';
			//innerDiv.cursor = '-moz-grabbing';
			this.innerDiv.cursor = 'url(' + this.root + '/openhand.cur.ico), default';
			if($('zahyou')){
				this.viewZahyou() ;
			}
			this.setZahyou();
		}
		this.checkTiles();
	},
	stopMove: function() {
		this.innerDiv.style.cursor = '';
		this.dragging = false;
	},
	checkTiles: function() {
		var visibleTiles = this.getVisibleTiles();

		var zoom = (this.zoom==0) ? 1 : 0;
		var limitX = this.zoomSizes[zoom][0] / this.tileSize -1
		var limitY = this.zoomSizes[zoom][1] / this.tileSize -1

		var visibleTilesMap = {};
		var innerDiv = this.innerDiv;
		var vl = visibleTiles.length;
		for (i = 0; i < vl; i++) {
			var tileArray = visibleTiles[i];
			var tileName = 'x' + tileArray[0] + 'y' + tileArray[1] + 'z' + this.zoom;
			if(tileArray[0] > limitX || tileArray[1] > limitY) tileName = 'spacer';
			
			visibleTilesMap[tileName] = true;
			var img = $(tileName);
			if (!img) {
				img = document.createElement('img');
				img.src = this.map_resources + tileName + '.gif';
				img.style.position = 'absolute';
				img.style.left = (tileArray[0] * this.tileSize) + 'px';
				img.style.top = (tileArray[1] * this.tileSize) + 'px';
				img.setAttribute('id', tileName);
				innerDiv.appendChild(img);
			}
		}
		var imgs = this.innerDiv.getElementsByTagName('img');
		var l = imgs.length;
		for (var i = 0; i < l; i++) {
			var id = imgs[i].getAttribute('id');
			if (!visibleTilesMap[id]) {
				if (id!='media_thumbnail'){
					innerDiv.removeChild(imgs[i]);
					i--;
					l--;
				}
			}
		}
	},
	getVisibleTiles: function() {
		var mapX = this.innerDiv.style.left.stripPx();
		var mapY = this.innerDiv.style.top.stripPx();

		var startX = Math.abs(Math.floor(mapX / this.tileSize)) -1 ;
		var startY = Math.abs(Math.floor(mapY / this.tileSize))  -1;

		var tilesX = Math.ceil(this.viewportWidth / this.tileSize) + 1;
		var tilesY = Math.ceil(this.viewportHight / this.tileSize) + 1;

		var visibleTileArray = [];
		var counter = 0;

		var starttilesX = tilesX + startX;
		var starttilesY = tilesY + startY;

		for (x = startX; x < starttilesX; x++) {
			for (y = startY; y < starttilesY; y++) {
				visibleTileArray[counter++] = [x, y];
			}
		}
		return visibleTileArray;
	},
	toggleZoom: function() {
		var mode = (this.zoom == 0) ? 'un' : '';
		this.zoom = (this.zoom == 0) ? 1 : 0;

		new OpacityObject('toggleZoomDiv', this.resources + mode + 'zoom').setBackground();

		if($('pinDialog')){
			$('pinDialog').style.display = 'none'
			$('pinDialog').innerHTML = '';
		}
		var imgs = this.innerDiv.getElementsByTagName('img');
		while (imgs.length > 0) this.innerDiv.removeChild(imgs[0]);

		var center = this.getCenterPoint();
		
		this.setInnerDivSize(this.zoomSizes[this.zoom][0], this.zoomSizes[this.zoom][1]);

		var zahyou = this.getInnerDivPoint(this.transZahyou(center[0]), this.transZahyou(center[1]));

		var X = zahyou[0];
		var Y = zahyou[1];
		this.setInnerDivPosition(X, Y);

		if($('pushPin')){
			this.removePin();
			this.PushPin(this.Setting.Pin);
		}
		if($('pushPin1')){
			this.removePinList();
			this.pushPinList(this.Setting.Pin);
		}
		this.checkTiles();
		if($('zahyou')){
			this.viewZahyou();
		}
	},
	clickZoom: function(event) {
		if (!event) event = window.event;
		this.moveCenter(event);
		this.toggleZoom();
	},
	toggleMapType: function() {
		this.map_resources = (this.map_resources.match(/real/)) ?
			this.Setting.map_resources : this.Setting.real_map_resources;
		var imgs = this.innerDiv.getElementsByTagName('img');
		while (imgs.length > 0) this.innerDiv.removeChild(imgs[0]);

		this.checkTiles();
	},
	moveCenter: function(event) {
		
		if(event.clientY < this.viewportHight / 2) {
			var moveX = - (this.viewportWidth / 2 - event.clientX);
			var moveY=  - (this.viewportHight / 2 - event.clientY);
		} else {
			var moveX = event.clientX - this.viewportWidth / 2;
			var moveY = event.clientY - this.viewportHight / 2;
		}

		var X = this.innerDiv.style.left.stripPx() - moveX;
		var Y = this.innerDiv.style.top.stripPx() - moveY;
		this.setInnerDivPosition(X, Y);
	},
	PushPin: function(pin) {

		var pinImage = document.createElement('div');

		var setpinX = (this.zoom == 1) ? 37/8 : 37/2.1;
		var setpinY = (this.zoom == 1) ? 34/2 : 34/0.6;

		var pinLeft = this.transPinZahyou(pin.x - setpinX)  + 'px';
		var pinTop = this.transPinZahyou(pin.y - setpinY) +'px';

		var pinStyle = pinImage.style;
		pinStyle.position = 'absolute';
		pinStyle.width = '37px';
		pinStyle.height = '34px';
		pinStyle.left = pinLeft;
		pinStyle.top = pinTop;
		pinStyle.zIndex = 1;

		pinImage.setAttribute('id', 'pushPin');
		this.innerDiv.appendChild(pinImage);
		new OpacityObject('pushPin', this.resources + 'pin').setBackground();
		/*
		var dialog = document.createElement('div');
		with(dialog.style){
			position = 'absolute';
			left = (pinImage.style.left.stripPx() - 90) + 'px';
			top = (pinImage.style.top.stripPx() - 210) + 'px';
			width = '309px';
			height = '229px';
			zIndex = 2;
		}
		dialog.setAttribute('id', 'pinDialog');
		dialog.innerHTML = '<table height="80%" width="80%">' + '<tr><td align="center">ピンの中に動画情報が<br>表示される予定です</td></tr></table>';
		this.innerDiv.appendChild(dialog);
		new OpacityObject('pinDialog', this.resources + 'dialog').setBackground();
		*/

		if(!location.href.match(/medias\/new|medias\/create/)){
			var zahyou = this.getInnerDivPoint(pinLeft.stripPx(), pinTop.stripPx());
			this.setInnerDivPosition(zahyou[0], zahyou[1]);
		}
		if($('zahyou')){
			this.viewZahyou() ;
			$('zahyou').innerHTML += 'ピンのためのスクロール:' + zahyou;
		}
	},
	pushPinList: function(pinList) {

		if(!$('pinDialog')){
			var dialog = document.createElement('div');

			var dialogStyle = dialog.style;
			dialogStyle.position = 'absolute';
			dialogStyle.left = '0px';
			dialogStyle.top = '0px';
			dialogStyle.width = '309px';
			dialogStyle.height = '229px';
			dialogStyle.zIndex = 2;
			dialogStyle.display = 'none';

			dialog.setAttribute('id', 'pinDialog');
			dialog.appendChild(document.createElement('div'));
			this.innerDiv.appendChild(dialog);
			new OpacityObject('pinDialog', this.resources + 'dialog').setBackground();
		}

		pinList.each(function(pin, i){
			var pinImage = document.createElement('div');

			var setpinX = (this.zoom == 1) ? 37/8 : 37/2.1;
			var setpinY = (this.zoom == 1) ? 34/2 : 34/0.6;

			var pinLeft = this.transPinZahyou(pin.x - setpinX)  + 'px';
			var pinTop = this.transPinZahyou(pin.y - setpinY) +'px';

			var pinStyle = pinImage.style;
			pinStyle.position = 'absolute';
			pinStyle.width = '37px';
			pinStyle.height = '34px';
			pinStyle.left = pinLeft;
			pinStyle.top = pinTop;
			pinStyle.zIndex = 1;
			pinStyle.cursor = 'pointer';

			pinImage.setAttribute('id', 'pushPin'+i);
			pinImage.onclick = function() {
				var dialogLeft = pinLeft.stripPx() - 90;
				var dialogTop = pinTop.stripPx() - 210;
				this.setDialogDivPosition(dialogLeft, dialogTop);
				this.setInnerDivCenterPosition(pinLeft.stripPx(), pinTop.stripPx());
				//var mode = (location.href.match(/hightube.jp/)) ? '/botanical-garden' : ''
				var mode = '';
				new Ajax.Updater('pinDialog', mode + '/medias/map_info/' + pin.id, {asynchronous:true, evalScripts:true});
				if ((browser.isIE55 || browser.isIE6x) && browser.isWin32)
					$('pinDialog').onclick = function(){location.href = 'http://' + location.host + mode + '/' + pin.id}
				$('pinDialog').style.display = 'block';
			}.bind(this);
			this.innerDiv.appendChild(pinImage);
			new OpacityObject('pushPin'+i, this.resources + 'pin').setBackground();

		}.bind(this));
	},
	removePin: function() {
		var pinImage = $('pushPin');
		if (pinImage) {
			pinImage.parentNode.removeChild(pinImage);
			//var dialog = $('pinDialog');
			//dialog.parentNode.removeChild(dialog);
		}
	},
	removePinList: function() {
		this.Setting.Pin.each(function(pin, i){
			var pinImage = $('pushPin' + i);
			if (pinImage) {
				pinImage.parentNode.removeChild(pinImage);
				/*
				var dialog = $('pinDialog');
				dialog.parentNode.removeChild(dialog);
				*/
			}
		});
	},
	pushPinPoint: function(event){
		if (!event) event = window.event;

		var position = Position;
		position.prepare();
		var divPosition = position.cumulativeOffset(this.outerDiv);
		var scrollPosition = position.realOffset(this.outerDiv);

		if (/Konqueror|Safari|KHTML/.test(navigator.userAgent) && event.clientY > position.deltaY) {
			var ecY = event.clientY - position.deltaY;
		}else{
			var ecY = event.clientY;
		}

		var pinTop = this.transPinZahyou(event.clientX + (position.deltaX - divPosition[0]));
		var pinLeft = this.transPinZahyou(ecY + (position.deltaY - divPosition[1]));
		
		if($('coordinate_x')){
			$('coordinate_x').value = pinTop*2;
			$('coordinate_y').value = pinLeft*2;
		}

         var setpinX = (this.zoom == 1) ? 37/8 : 37/2.1;
         var setpinY = (this.zoom == 1) ? 34/2 : 34/0.6;

		if($('debug')){
			var temp = 'eX'+event.clientX+'eY'+ecY+'Px:'+position.deltaX+'Py:'+position.deltaY;
			$('debug').innerHTML = temp;
		}
		this.removePin();
		var point = {x:pinTop-setpinX, y:pinLeft-setpinY};
		this.PushPin(point);
	},
  setInnerDivSize: function(width, height) {
	this.innerDiv.style.width = width + 'px';
	this.innerDiv.style.height = height + 'px';
  },
  setInnerDivPosition: function(X, Y) {
		this.innerDiv.style.left = X + 'px';
		this.innerDiv.style.top = Y + 'px';
	},
  setInnerDivCenterPosition: function(X, Y) {
		this.innerDiv.style.left = this.viewportWidth/2 - X - 100 + 'px';
		this.innerDiv.style.top = this.viewportHight/2 -  Y - 100 + 'px';
	},
  setDialogDivPosition: function(X, Y) {
		$('pinDialog').style.left = X + 'px';
		$('pinDialog').style.top = Y + 'px';
	},
	transZahyou: function(zahyou){
		return (this.zoom==1) ? zahyou * 2 : zahyou / 2;
	},
	transPinZahyou: function(zahyou){
		return (this.zoom==1) ? zahyou : zahyou / 2;
	},
	getCenterPoint: function() {
		var centerWidth =  this.viewportWidth / 2 -  this.innerDiv.style.left.stripPx() - 5.5;
		var centerHight = this.viewportHight / 2 -  this.innerDiv.style.top.stripPx() - 5.5;
		return [centerWidth, centerHight]
	},
	getInnerDivPoint: function(X, Y) {
		var innerWidth =  this.viewportWidth / 2 - X  - 5.5;
		var innerHeight = this.viewportHight / 2 -  Y - 5.5;
		return [innerWidth, innerHeight]
	},
	viewZahyou: function() {
		var areaPoint = this.innerDiv.style.left + ',' + this.innerDiv.style.top;

		var centerPoint = this.getCenterPoint();
		var pinPoint = this.getInnerDivPoint(centerPoint[0], centerPoint[1]);

		$('zahyou').innerHTML = '内側の左上:' + areaPoint + ' 中心点:' + centerPoint + '割り出した左上:' + pinPoint;

	},
	setZahyou: function(){
		if($('coordinate_x')){
			var centerPoint = this.getCenterPoint();
			$('coordinate_x').value = centerPoint[0];
			$('coordinate_y').value = centerPoint[1];
		}
	}
}
String.prototype.stripPx = function() {
	if (this == '') return 0;
	//return parseFloat(this.substring(0, this.length - 2));
	return parseFloat(this.toString().split('px')[0]); 
}
