var Fluid = {
	UI: {},
	Canvas: {}
};

Fluid.Canvas = new Class({
	Implements: [Events, Options],
	options: {
		oCanvas:{}
	},
	canvas: null,
	initialize:function(ele, options){
		this.setOptions(options);
		this.ele = $(ele);
		this.oCanvas = this.options.oCanvas;		
		this.createCanvas();
	},
	props: {'position': 'absolute', 'top': 0, 'left': 0},
	createCanvas: function(){
		this.canvas = new Element('canvas',{'width': this.oCanvas.w, 'height': this.oCanvas.h, 'styles': this.props});
		this.wrapper = new Element('div', {'styles': {'width': this.oCanvas.w, 'height': this.oCanvas.h, 'position': 'relative', margin: this.ele.getStyle('margin')}});
		this.ele.set('styles', this.props);
		this.canvas.inject(this.wrapper);
		this.wrapper.inject(this.ele,'after');
		this.ele.inject(this.wrapper);
		this.initCanvas();
	},
	initCanvas: function(){
		this.ctx = this.canvas.getCtx('2d');
		this.draw();
	}
});


/* Canvas Utilities */
Fluid.Canvas.implement({
	draw: function(){
		this.oCanvas.shapes.each(function(shape, index){
			this.color = shape.color;							  
			this[shape.stroketype].run(shape.color, this)							  
			this[shape.shapetype].run(shape.coords, this);
			(shape.stroketype == 'fill') ? this.ctx.fill() : this.ctx.stroke();
		}.bind(this));
	}
});

/* Canvas Fills */
Fluid.Canvas.implement({
	fill: function(color){
		console.log(this.color);
		if($type(this.color) != 'array'){
			this.ctx.fillStyle = col[0].setRgba(col[1]);
		} else {
			this.stops = 1 / this.color.length ;
			this.lingrad = this.ctx.createLinearGradient(0,0,0, this.oCanvas.h);
			
			this.color.each(function(col, ind){
				this.lingrad.addColorStop(this.stops * (ind + 1), col[0].setRgba(col[1]));				
			}.bind(this));
			
			this.ctx.fillStyle = this.lingrad;	
		}
	},
	stroke: function(color){
		if($type(color) != 'array'){
			this.ctx.strokeStyle = color.setRgba(1);
		}
	}
});

/* Canvas Drawing */
Fluid.Canvas.implement({
	roundedRect: function(shape){
		this.ctx.beginPath();
		this.ctx.moveTo(shape.x, shape.y + shape.r);
		this.ctx.lineTo(shape.x, shape.y + shape.h - shape.r);
		this.ctx.quadraticCurveTo(shape.x, shape.y + shape.h, shape.x + shape.r, shape.y + shape.h);
		this.ctx.lineTo(shape.x + shape.w - shape.r, shape.y + shape.h);
		this.ctx.quadraticCurveTo(shape.x + shape.w, shape.y + shape.h, shape.x + shape.w, shape.y + shape.h - shape.r);
		this.ctx.lineTo(shape.x + shape.w, shape.y + shape.r);
		this.ctx.quadraticCurveTo(shape.x + shape.w, shape.y, shape.x + shape.w - shape.r, shape.y);
		this.ctx.lineTo(shape.x + shape.r, shape.y);
		this.ctx.quadraticCurveTo(shape.x, shape.y, shape.x, shape.y + shape.r);
	}						 
});

String.implement({
	setRgba: function(alpha){
		var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
		var rgb = hex.slice(1);
		
		if (rgb.length != 3) return null;
		var rgb = rgb.map(function(value){
			if (value.length == 1) value += value;
			return value.toInt(16);
		});
		
		return 'rgba(' + rgb + ',' + alpha + ')';
	}
});

Element.implement({
	getCtx: function(cntxt){
		if(this.get('tag') != 'canvas') return null;
		return this.getContext(cntxt);
	}
});		

Fluid.UI = new Class({
	Implements: [Events, Options],
	options: {
		onClick: $empty,
		onMouseOver: $empty,
		onMouseOut: $empty				
	},
	initialize: function(ele, options){
		this.setOptions(options);
		$(ele).addEvents({
			'click': this.clickHandler.bindWithEvent(this),
			'mouseover': this.mouseoverHandler.bindWithEvent(this),
			'mouseout': this.mouseoutHandler.bindWithEvent(this)
		});				
	},
	clickHandler: function(evt){this.fireEvent('onClick', [evt]);},
	mouseoverHandler: function(evt){this.fireEvent('onMouseOver', [evt]);},
	mouseoutHandler: function(evt){this.fireEvent('onMouseOut', [evt]);}
});

Fluid.UI.CanvasButton = new Class({
	Extends: Fluid.UI,
	options: {
		onClick: $empty,
		onMouseOver: $empty,
		onMouseOut: $empty,
		canvas:{
			bgcolor: '',
			fgcolor: '',
			radius: 0,
			padding: 0
		}

	},
	initialize: function(ele, options){
		this.setOptions(options);
		this.parent(ele, options);
		this.ele = $(ele);
		this.size = this.ele.getSize();	
		
		this.oCanvas = {
			w: this.size.x, 
			h: this.size.y,			
			shapes: new Hash({
				bg: {shapetype:'roundedRect', stroketype:'fill', color:this.options.canvas.bgcolor, coords: {x:0, y:0, h:this.size.y, w:this.size.x, r:this.options.canvas.radius}},
				fg: {shapetype:'roundedRect', stroketype:'fill', color:this.options.canvas.fgcolor, coords: {x:this.options.canvas.padding, y:this.options.canvas.padding, h:this.size.y - (this.options.canvas.padding * 2), w:this.size.x - (this.options.canvas.padding * 2), r:this.options.canvas.radius}}					  
			})
		};
		
		this.eCanvas = new Fluid.Canvas(this.ele, {oCanvas: this.oCanvas});
		
		return this.eCanvas;
	}
});

Element.implement({
	setCanvasBtn: function(opts){
		new Fluid.UI.CanvasButton(this, opts);
		return this;
	}
});		

window.addEvent('domready', function(){
	$('red').setCanvasBtn({
		canvas:{
			bgcolor: [['#FF0000',1],['#FF0000',.75]],
			fgcolor: [['#FFFFFF',0.1],['#FFFFFF',0.5]],
			radius: 4,
			padding: 2
		},
		onClick: function(e){ alert(e.target.id); }
	});		
	$('purple').setCanvasBtn({
		canvas:{
			bgcolor: [['#923FF8',1],['#923FF8',.75]],
			fgcolor: [['#FFFFFF',0.08],['#FFFFFF',0.5]],
			radius: 4,
			padding: 2
		},
		onClick: function(e){ alert(e.target.id); }
	});	
});
