
var Modal = Class.create();

Modal.prototype = {
	
	initialize: function(target, options){
	
		$$(target).each(function(item){
			item.onclick = function(){return false;}
			var href = item.readAttribute("href");
			item.observe("click", this.open.bind(this, href));
		}.bind(this));
	
		if(options == null){
			options = {};
		}
		if(options.zIndex == null){
			options.zIndex = 100;
		}
		this.initialOptions = Object.clone(options);
		this.options = Object.clone(options);
		this.objBody = $$('body')[0];
	},
	
	open: function(url){
		var queryParams = url.toQueryParams();

		this.options = Object.clone(this.initialOptions);
		Object.extend(this.options, queryParams);
		
		if(this.options.before){
			eval(this.options.before);
		}
		
		if(url.indexOf("?") < 0){
			url = url + "?rnd="+Math.floor(Math.random()*100);
		}else{
			url = url + "&rnd="+Math.floor(Math.random()*100);
		}

		new Ajax.Request(url, {
			method: 'get',
			onSuccess: this.start.bind(this)
		});
	},
	
	start: function(transport){
		this.modalOverlay = this.createOverlay(this.options);
		this.modalOverlay.hide();

		var content = this.parseTransport(transport);
		this.modalContainer = this.createContainer(content, this.options);

		this.objBody.appendChild(this.modalOverlay);
		this.objBody.appendChild(this.modalContainer);

		this.repositionContainer(this.modalContainer, this.options);


		this.modalBackground.hide();
		this.modalContent.hide();
		this.closeButton.hide();

		this.modalOverlay.appear({duration: 0.3, to: 0.4, queue:'front'});

		if(this.options.noscale){
			this.modalBackground.appear({duration: 0.3, queue: 'front'});
		}else{
			this.modalBackground.grow({duration: 1, queue: 'front'});
		}
		this.modalContent.appear({duration: 0.3, queue: 'end'});
		
		if(this.options.after){
			this.closeButton.appear({duration: 0.3, queue: 'end', afterFinish:function(){eval(this.options.after);}.bind(this)});
		}else{
			this.closeButton.appear({duration: 0.3, queue: 'end'});
		}


	},
	
	close: function(){
	
		Event.stopObserving(window, 'resize', this.centeringVertical);
		Event.stopObserving(window, 'resize', this.centeringHorizontal);
	
		this.modalContainer.fade({duration: 0.3, queue: 'front'});
		this.modalOverlay.fade({duration: 0.3, queue: 'end', afterFinish:function(){
			this.objBody.removeChild(this.modalOverlay);
			this.objBody.removeChild(this.modalContainer);
			this.modalOverlay = null;
			this.modalContainer = null;
			this.modalContent = null;
			this.modalBackground = null;
			this.closeButton = null;
			if(this.options.close){
				eval(this.options.close);
			}
		}.bind(this)});
	},
	
	createOverlay: function(options){

		overlay = new Element('div');
		overlay.addClassName('modalOverlay');
		this.addClass(overlay, options, 'overlayClass');
		
		overlay.setStyle({
			zIndex:options.zIndex
		});
		
		overlay.observe('click', this.close.bind(this));
		
		return overlay;
	},
	
	parseTransport: function(transport){
		var text = transport.responseText;

		var content = new Element('div');
		content.update(text);
		
		return content.select('div')[0];
	},
	
	createContainer: function(content, options){

		var container = new Element('div');
		container.addClassName('modalContainer');
		this.addClass(container, options, 'containerClass');

		var background = new Element('div');
		background.addClassName('modalBackground');
		this.addClass(background, options, 'backgroundClass');
		this.modalBackground = background;
		
		var modal = new Element('div');
		modal.addClassName('modal');
		this.addClass(modal, options, 'modalClass');
		this.modalContent = modal;

		var closeButton = new Element('p');
		closeButton.addClassName('closeButton');
		this.addClass(closeButton, options, 'closeButtonClass');
		this.closeButton = closeButton;

		
		if(options['backgroundClass'] != null){
			closeButton.update('<a href="#close" ><img src="images/close_green.png" title="back/戻る" /></a>');
		}else{
			closeButton.update('<a href="#close" ><img src="images/close.png" title="back/戻る" /></a>');
		}
		
		closeButton.onclick = function(){return false;};
		closeButton.observe('click', this.close.bind(this));
		
		modal.appendChild(content);
		
		container.appendChild(background);
		container.appendChild(closeButton);
		container.appendChild(modal);
		
		modal.setStyle({
			zIndex:options.zIndex+20
		});
		closeButton.setStyle({
			zIndex:options.zIndex+30
		});
		container.setStyle({
			zIndex:options.zIndex+10
		});
		
		return container;
	},
	
	repositionContainer: function(container, options){

		this.setStyle(container, options, 'width');
		this.setStyle(container, options, 'top');
		this.setStyle(container, options, 'height');
		
		var heightStr = '';
		if(container.getStyle('height')){
			heightStr = container.getStyle('height');
		}else{
			var heightStr = container.getHeight(); + 'px';
		}
		container.setStyle({height:heightStr});
		
		this.centeringHorizontal(container);
		Event.observe(window, 'resize', this.centeringHorizontal.bind(this, container));
		
		if(options['top'] != null && options['top'] == 'auto'){
			this.centeringVertical(container);
			Event.observe(window, 'resize', this.centeringVertical.bind(this, container));
		}
	},
	
	setStyle: function(target, options, optionName){
		if(options[optionName] != null){
			var style = {};
			style[optionName] = options[optionName]
			target.setStyle(style);
		}
	},
	
	addClass: function(target, options, optionName){
		if(options[optionName] != null){
			target.addClassName(options[optionName]);
		}
	},
	
	centeringHorizontal: function(target){
		var marginLeft = target.getWidth() / 2;
		var bodyWidth = this.objBody.getWidth();
		if(bodyWidth/2 < marginLeft){
			marginLeft = bodyWidth/2 * -1;
		}else{
			marginLeft = marginLeft * -1;
		}
		var marginLeftStr = marginLeft + "px";
		target.setStyle({
			marginLeft:marginLeftStr
		});
	},
	
	centeringVertical: function(target){
		var marginTop = target.getHeight() / 1.9;
		var bodyHeight = this.objBody.getHeight();
		if(bodyHeight/2 < marginTop){
			marginTop = bodyHeight/2 * -1;
		}else{
			marginTop = marginTop * -1;
		}
		var marginTopStr = marginTop + "px";
		target.setStyle({
			top: '50%',
			marginTop:marginTopStr
		});
	}
};