/*
Script:
	mocha.js
	
Author:
	Greg Houston, <http://greghoustondesign.com/>
 
License:
	MIT-style license.
*/

var mochaDesktop = new Class({
	options: {
		headerHeight: 25,
		footerHeight: 30,
		cornerRadius: 9,
		desktopTopOffset: 10, // use a negative number if neccessary to place first window where you want it
		desktopLeftOffset: 330,
		mochaTopOffset: 80, // initial vertical spacing of each window
		mochaLeftOffset: 80, // initial horizontal spacing of each window
		newWindowPosTop: 0, // In the current setup this just initializes the variable and does not effect the position
		newWindowPosLeft: 0, // In the current setup this just initializes the variable and does not effect the position
		minWidth: 250, // minimum width of windows when resize
		maxWidth: 2500, // maximum width of windows when resized
		minHeight: 100,	// minimum height of windows when resized	
		maxHeight: 2000 // maximum height of windows when resized
	},
	initialize: function(options){		
		this.setOptions(options);
		this.indexLevel = 1;
		new Element('canvas');		
		// Add properties to elements in the DOM
		Element.implement({oldTop: ''});
		Element.implement({oldLeft: ''});
		Element.implement({oldWidth: ''});
		Element.implement({oldHeight: ''});
		Element.implement({retoreMaxToggle: 'maximize'});	
		this.setDesktopSize();
		$$('#mochaDesktop div.mocha').setStyle('display', 'block'); 	
		this.insertAll($$('#mochaDesktop div.mocha'));
		this.drawAll();		
		this.displayAll();
		this.initializeDrag($$('#mochaDesktop div.mocha'));		
		this.addExternalControls();		
		this.addSlider();
		window.onresize = function(){		
			this.setDesktopSize();
			setTimeout( function(){
				this.drawAll();
			}.bind(this), 100);				
		}.bind(this)						
	},
	newWindowFromForm: function(){
		var mochaNewWindow = new Element('div', {
			'class': 'mocha'
		}).setHTML($('mochaNewWindowFormContent').value).injectInside($('mochaDesktop'));
		mochaNewWindow.setStyles({
			width: 300,
			height: 125,
			display: 'block'			
		})	
		new Element('h3', {
			'class': 'mochaTitle'
		}).setHTML($('mochaNewWindowFormHeaderTitle').value).injectTop(mochaNewWindow);
		this.insertAll([mochaNewWindow]);
		this.drawWindow(mochaNewWindow);
		this.initializeDrag([mochaNewWindow]);
		this.indexLevel++;					  
        mochaNewWindow.setStyle('zIndex', this.indexLevel);		

		if (window.webkit == true ) {
			this.options.newWindowPosTop = (window.innerHeight.toInt() * .5) - (mochaNewWindow.getStyle('height').toInt() * .5);		
			this.options.newWindowPosLeft = (window.innerWidth.toInt() * .5) - (mochaNewWindow.getStyle('width').toInt() * .5);
		} else {
			this.options.newWindowPosTop = (window.getHeight().toInt() * .5) - (mochaNewWindow.getStyle('height').toInt() * .5);				
			this.options.newWindowPosLeft = (window.getWidth().toInt() * .5) - (mochaNewWindow.getStyle('width').toInt() * .5);
		}
		var mochaMorph = new Fx.Morph(mochaNewWindow, {
			'duration': 300				
			});				
		mochaMorph.start({		
				'top': this.options.newWindowPosTop,
				'left': this.options.newWindowPosLeft
		});	
		this.addExternalControls();
	},
	newWindow: function(h, w, t, c, e){
		var mochaNewWindow = new Element('div', {
			'class': 'mocha'
		}).setHTML(c).injectInside($('mochaDesktop'));
		mochaNewWindow.setStyles({
			width: w,
			height: h,
			display: 'block'			
		})	
		new Element('h3', {
			'class': 'mochaTitle'
		}).setHTML(t).injectTop(mochaNewWindow);
		this.insertAll([mochaNewWindow]);
		this.drawWindow(mochaNewWindow);
		this.initializeDrag([mochaNewWindow]);
		this.indexLevel++;					  
        mochaNewWindow.setStyle('zIndex', this.indexLevel);		

		if (window.webkit == true ) {
			this.options.newWindowPosTop = (window.innerHeight.toInt() * .5) - (mochaNewWindow.getStyle('height').toInt() * .5);		
			this.options.newWindowPosLeft = (window.innerWidth.toInt() * .5) - (mochaNewWindow.getStyle('width').toInt() * .5);
		} else {
			this.options.newWindowPosTop = (window.getHeight().toInt() * .5) - (mochaNewWindow.getStyle('height').toInt() * .5);				
			this.options.newWindowPosLeft = (window.getWidth().toInt() * .5) - (mochaNewWindow.getStyle('width').toInt() * .5);
		}
		var mochaMorph = new Fx.Morph(mochaNewWindow, {
			'duration': e				
			});				
		mochaMorph.start({		
				'top': this.options.newWindowPosTop,
				'left': this.options.newWindowPosLeft
		});	
		this.addExternalControls();
	},
	setDesktopSize: function(){
			if (window.webkit == true ) {
				$('mochaDesktop').setStyle('width', (window.innerWidth - 20) + 'px'); // To adjust for scrollbar
				setTimeout( function(){
					$('mochaDesktop').setStyle('width', window.innerWidth + 'px');
				}.bind(this),100);										
				$('mochaDesktop').setStyle('height', window.innerHeight + 'px');
				$('mochaPageWrapper').setStyle('height', window.innerHeight + 'px');
				$('mochaPage').setStyle('height', window.innerHeight + 'px');		
			}
			else {
				$('mochaDesktop').setStyle('width', (window.getWidth() - 20) + 'px'); // To adjust for scrollbar
				setTimeout( function(){
					$('mochaDesktop').setStyle('width', window.getWidth() + 'px');
				}.bind(this),100);					
				$('mochaDesktop').setStyle('height', window.getHeight() + 'px');
				//$('mochaPageWrapper').setStyle('height', window.getHeight() + 'px');
				//$('mochaPage').setStyle('height', window.getHeight() + 'px');					
			}	
	},	
	insertAll: function(elementArray){
		elementArray.each(function(el){
			var mochaTempContents = el.innerHTML;
			el.empty();
			
			var mochaOverlay = new Element('div', {
    			'class': 'mochaOverlay',
				'display': 'none'
			}).injectInside(el);

			//Insert mochaTitlebar		
			var mochaTitlebar = new Element('div', {
    			'class': 'mochaTitlebar'
			}).injectTop(mochaOverlay);			
			
			var mochaContent = new Element('div', {
    			'class': 'mochaContent'
			}).injectInside(mochaOverlay);
			
			mochaContent.setStyles({
				width: el.getStyle('width'),
				height: el.getStyle('height')
			});				
			
			var mochaScroller = new Element('div', {
    			'class': 'mochaScroller'
			}).injectTop(mochaContent);
			
			var mochaScrollerpad = new Element('div', {
    			'class': 'mochaScrollerpad'
			}).setHTML(mochaTempContents).injectInside(mochaScroller);										

			var mochaTitlebarH3 = $E('h3.mochaTitle', mochaScrollerpad).clone().injectInside(mochaTitlebar);
			$E('.mochaTitle', mochaScrollerpad).remove();
	
			//Insert canvas
			var canvas = new Element('canvas', {
    			'class': 'mochaCanvas'
			}).injectInside(el);			
			canvas.width = 1;
			canvas.height = 1;
			
			// Dynamically initialize canvas using excanvas. This is only required by IE
			if (/msie/i.test(navigator.userAgent)) {
				G_vmlCanvasManager.initElement(canvas);
			}
						
			//Insert resize handles
			new Element('div', {
    			'class': 'resizeHandle'
			}).injectAfter(mochaOverlay);
			
			//Insert mochaTitlebar controls
			new Element('div', {
    			'class': 'mochControls'
			}).setHTML('<div class="mochaClose"></div><div class="restoreMaxToggle"></div>').injectAfter(mochaOverlay);					
		});			
	},
	drawAll: function(){
		$$('#mochaDesktop div.mocha').each(function(mocha){
			this.drawWindow(mocha);
		}.bind(this));	
	},
	displayAll: function(){
		$$('#mochaDesktop div.mocha').each(function(el){
			this.options.desktopTopOffset = this.options.desktopTopOffset + this.options.mochaTopOffset;
			this.options.desktopLeftOffset = this.options.desktopLeftOffset + this.options.mochaLeftOffset;
				var mochaMorph = new Fx.Morph(el, {
					'duration': 550				
				});				
				mochaMorph.start({		
					'top': this.options.desktopTopOffset,
					'left': this.options.desktopLeftOffset
				});		
		}.bind(this));
	},
	drawWindow: function(mocha, shadows) {
		var mochaOverlay = $E('.mochaOverlay', mocha); 
		var mochaContent = $E('.mochaContent', mocha); 
		var mochaScroller = $E('.mochaScroller', mocha);
		var mochaTitlebar = $E('.mochaTitlebar', mocha);		
		var mochaCanvas = $E('.mochaCanvas', mocha);
		var ctx = mochaCanvas.getContext('2d');
		
		if (mocha.retoreMaxToggle == 'restore') {
			mochaContent.setStyle('height', ($('mochaDesktop').getStyle('height').toInt() - this.options.headerHeight - this.options.footerHeight + 6));
			mochaContent.setStyle('width', $('mochaDesktop').getStyle('width').toInt());		
		}		

 		mochaScroller.setStyle('height', mochaContent.getStyle('height'));
 		mochaScroller.setStyle('width', mochaContent.getStyle('width'));
	
		mochaHeight = mochaContent.scrollHeight;
		mochaWidth = mochaContent.scrollWidth + 6;
	
		//set height 
		mochaHeight = mochaHeight + this.options.headerHeight + this.options.footerHeight;
	 	mochaOverlay.setStyle('height', mochaHeight);	
		$(mocha).setStyle('height', mochaHeight);

		//test for Safari
		if (window.webkit == true ) {
			mochaCanvas.setProperties({
    			'width': 4000,
    			'height': 2000
			});	
		} else {
			mochaCanvas.width = mochaWidth;
			mochaCanvas.height = mochaHeight;			

		}
		// set width		
		mochaOverlay.setStyle('width', mochaWidth); 
		$(mocha).setStyle('width', mochaWidth);
		mochaTitlebar.setStyle('width', mochaWidth - 6);
	
    	// Draw shapes
		ctx.clearRect(0,0,$('mochaDesktop').getStyle('width').toInt(),$('mochaDesktop').getStyle('height').toInt());
		if (shadows == null || shadows == false && window.ie != true){
			this.roundedRect(ctx,0,0,mochaWidth,mochaHeight,this.options.cornerRadius,0,0,0,0.06); //shadow
			this.roundedRect(ctx,1,1,mochaWidth-2,mochaHeight-2,this.options.cornerRadius,0,0,0,0.08); //shadow
			this.roundedRect(ctx,2,2,mochaWidth-4,mochaHeight-4,this.options.cornerRadius,0,0,0,0.3); //shadow
		}		
		this.roundedRect(ctx,3,2,mochaWidth-6,mochaHeight-6,this.options.cornerRadius,33,33,33,1.0);	//mocha body
		this.topRoundedRect(ctx,3,2,mochaWidth-6,this.options.headerHeight,this.options.cornerRadius); //mocha header
		this.triangle(ctx,mochaWidth-20,mochaHeight-20,12,12,209,209,209,1.0); //resize handle
		this.restorebutton(ctx,mochaWidth-34,15,217,240,217,1.0);	
		this.closebutton(ctx,mochaWidth-15,15,240,217,217,1.0);
		this.triangle(ctx,mochaWidth-20,mochaHeight-20,10,10,0,0,0,0); //invisible dummocha. The last element drawn is not rendered consistently while resizing in IE6 and IE7.
	},
	//mocha body
	roundedRect: function(ctx,x,y,width,height,radius,r,g,b,a){
		ctx.fillStyle = 'rgba(' + r +',' + g + ',' + b + ',' + a + ')';
		ctx.beginPath();
		ctx.moveTo(x,y+radius);
		ctx.lineTo(x,y+height-radius);
		ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
		ctx.lineTo(x+width-radius,y+height);
		ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
		ctx.lineTo(x+width,y+radius);
		ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
		ctx.lineTo(x+radius,y);
		ctx.quadraticCurveTo(x,y,x,y+radius);
		ctx.fill(); 
	},
	//mocha header with gradient background
	topRoundedRect: function(ctx,x,y,width,height,radius){

		// Create gradient		
		if (window.opera != null ){
			var lingrad = ctx.createLinearGradient(0,0,0,this.options.headerHeight+2);			
		}
		else {
			var lingrad = ctx.createLinearGradient(0,0,0,this.options.headerHeight);		
		}
		lingrad.addColorStop(0, 'rgba(77,77,77,100)');
		lingrad.addColorStop(1, 'rgba(0,0,0,100)');
		ctx.fillStyle = lingrad;

		// draw header
		ctx.beginPath();
		ctx.moveTo(x,y);
		ctx.lineTo(x,y+height);
		ctx.lineTo(x+width,y+height);
		ctx.lineTo(x+width,y+radius);
		ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
		ctx.lineTo(x+radius,y);
		ctx.quadraticCurveTo(x,y,x,y+radius);	
		ctx.fill(); 
	},
	// resize handle
	triangle: function(ctx,x,y,width,height,r,g,b,a){
		ctx.beginPath();
		ctx.moveTo(x+width,y);
		ctx.lineTo(x,y+height);
		ctx.lineTo(x+width,y+height);
		ctx.closePath();
		ctx.fillStyle = 'rgba(' + r +',' + g + ',' + b + ',' + a + ')';	
		ctx.fill();
	},
	restorebutton: function(ctx,x,y,r,g,b,a){
		//circle
		ctx.beginPath();
		ctx.moveTo(x,y);		
		ctx.arc(x,y,7,0,Math.PI*2,true);
		ctx.fillStyle = 'rgba(' + r +',' + g + ',' + b + ',' + a + ')';	
		ctx.fill();						
		//plus sign
		ctx.beginPath();
		ctx.moveTo(x,y-4);
		ctx.lineTo(x,y+4);								
		ctx.stroke();
		ctx.beginPath();
		ctx.moveTo(x-4,y);
		ctx.lineTo(x+4,y);								
		ctx.stroke();		
	},
	closebutton: function(ctx,x,y,r,g,b,a){
		//circle
		ctx.beginPath();
		ctx.moveTo(x,y);					
		ctx.arc(x,y,7,0,Math.PI*2,true);
		ctx.fillStyle = 'rgba(' + r +',' + g + ',' + b + ',' + a + ')';
		ctx.fill();
		//plus sign
		ctx.beginPath();
		ctx.moveTo(x-3,y-3);
		ctx.lineTo(x+3,y+3);								
		ctx.stroke();
		ctx.beginPath();
		ctx.moveTo(x+3,y-3);
		ctx.lineTo(x-3,y+3);								
		ctx.stroke();		
	},				
	initializeDrag: function(elementArray){
		elementArray.each(function(el){
			// Draggable
			var mochaHandle = $E('.mochaTitlebar', el)	
			new Drag.Move(el, {
				handle: mochaHandle,
				onStart: function(){  
					this.indexLevel++;					  
                	el.setStyle('zIndex', this.indexLevel); 
            	}.bind(this)			
			});
			// Resizable
			var mochaContent = $E('.mochaContent', el);
			var resizeHandle = $E('.resizeHandle', el);			
			mochaContent.makeResizable({
				handle: resizeHandle,
				modifiers: {x: 'width', y: 'height'},
				limit: { x:[this.options.minWidth,this.options.maxWidth], y:[this.options.minHeight,this.options.maxHeight] }, 							
				onDrag: function(){
					this.drawWindow(el);		
				}.bind(this)		
			});			
		}.bind(this));	
		elementArray.each(function(element) {
			element.addEvent('click', function(event){	
				this.indexLevel++;
                element.setStyle('zIndex', this.indexLevel); 
			}.bind(this));			
		}.bind(this));
		// Restore / Maximize Window
		elementArray.each(function(element) {
			$E('.restoreMaxToggle', element).addEvent('click', function(event){		
				var mochControls = event.target.parentNode;
				var el = mochControls.parentNode;
				if (el.retoreMaxToggle == 'maximize') {
					this.maximizeWindow(el);
				} else {
					this.restoreWindow(el);
				}			
			}.bind(this));
		}.bind(this));
		// Close Window
		elementArray.each(function(element) {
			$E('.mochaClose', element).addEvent('click', function(event){
				var mochControls = event.target.parentNode;
				var el = mochControls.parentNode;			
				this.drawWindow(el, false);	
				el.effect('opacity', { duration: 150 }).start(.4);
				setTimeout(function(){
					el.remove();
				}, 150);				
			}.bind(this));
		}.bind(this));						
	},
	addExternalControls: function(){		
		$$('a.mochaMakeWindow').removeEvents();
		$$('a.mochaMakeWindow').addEvent('click', function(e) {
			this.newWindow(300, 200, 'New Window', '<h3><a href="#" class="mochaMakeWindow">MAKE A WINDOW!</a></h3>', 300);			
		}.bind(this));
		/*$$('#mochaDesktop a.mochaNewWindow').addEvent('click', function(event){
			this.newWindow();
			return false;		
		}.bind(this));						
		*/
	},				
	addSlider: function(){
		if ($('sliderarea')) {
		this.mochaSlide = new Slider($('sliderarea'), $('sliderknob'), {
			steps: 20,	
			offset: 5,
			onChange: function(pos){
				$('updatevalue').setHTML(pos);
				this.options.cornerRadius = pos;
				this.drawAll();
				this.indexLevel++;  
        		//$('drag03').setStyle('zIndex', this.indexLevel);			
			}.bind(this) 	
		}).set(this.options.cornerRadius);
		}
	},
	maximizeWindow: function(el) {
		var mochaContent = $E('.mochaContent', el);	

		$(el).oldTop = $(el).getStyle('top');
		$(el).oldLeft = $(el).getStyle('left');
		mochaContent.oldWidth = mochaContent.getStyle('width');
		mochaContent.oldHeight = mochaContent.getStyle('height');

		var mochaMorph = new Fx.Morph(el, { 
			'duration': 200,			 	
			'onComplete': function(el){
 				mochaContent.setStyle('height', ($('mochaDesktop').getStyle('height').toInt() - this.options.headerHeight - this.options.footerHeight + 6));
 				mochaContent.setStyle('width', $('mochaDesktop').getStyle('width').toInt());		
				this.drawWindow(el);
				}.bind(this)			 	
		});	
		mochaMorph.start({		
			'top': -3,
			'left': -3
		});
		$(el).retoreMaxToggle = 'restore';
	},
	restoreWindow: function(el) {
		var mochaContent = $E('.mochaContent', el);	
		mochaContent.setStyle('width', mochaContent.oldWidth);
		mochaContent.setStyle('height', mochaContent.oldHeight);
		$(el).retoreMaxToggle = 'maximize';			
		this.drawWindow(el);
		var mochaMorph = new Fx.Morph(el, { 
			'duration': 150		 	
		});	
		mochaMorph.start({		
			'top': $(el).oldTop,
			'left': $(el).oldLeft
		});
	}
});
mochaDesktop.implement(new Options, new Events);

window.addEvent('domready', function(){

	var myDesktop = new mochaDesktop();
	//myDesktop.newWindow();
				
})