function HexToR(h) {return parseInt((cutHex(h)).substring(0,2),16)}
function HexToG(h) {return parseInt((cutHex(h)).substring(2,4),16)}
function HexToB(h) {return parseInt((cutHex(h)).substring(4,6),16)}
function cutHex(h) {return (h.charAt(0)=="#") ? h.substring(1,7):h}
pi = Math.PI;

var canvasElements = [];

/*
@params
1 - name
2 - area
3 - shadow
4 - border
5 - gradient
*/
function styleCanvas(element) {
    this.element = element;
    var opts;
    var opt_name = ['area','shadow','border','gradient'];
    for (i=1;i < 5;i++) {
        if (arguments[i] && arguments[i] instanceof Object) {
            opts = arguments[i];
            for (var propertyName in opts) {
                if (!(opts[propertyName] instanceof Function)) {
                    if (this[opt_name[i-1]+'_'+propertyName] != undefined) {
                        if (i==2 && propertyName=='color') opts[propertyName] = HexToR(opts[propertyName])+','+HexToG(opts[propertyName])+','+HexToB(opts[propertyName]);
                        this[opt_name[i-1]+'_'+propertyName] = opts[propertyName];
                    }
                }
            }
        }
    }
    var $canvas = $('<canvas width="0" height="0" style="position:absolute;top:0px;left:0px;margin-top:'+this.element.css('margin-top')+';margin-right:'+this.element.css('margin-right')+';margin-bottom:'+this.element.css('margin-bottom')+';margin-left:'+this.element.css('margin-left')+';"></canvas>');
    this.canvas = $canvas.get(0);
    this.element.before($canvas);
    if (window.G_vmlCanvasManager) {
      this.canvas = G_vmlCanvasManager.initElement(this.canvas);
    }
	this.ctx = this.canvas.getContext("2d");
    this.element.css({background:'transparent',border:'none'});
	if ($canvas.parent().css('position') != 'absolute') $canvas.parent().css({position:'relative'});
    if (this.element.css('position') != 'absolute') this.element.css({position:'relative'});
	this.element.css({padding:(this.area_padding+this.shadow_size)});
	
    canvasElements.push(this);
    
    var w = this.element.outerWidth();
    var h = this.element.outerHeight();
    
    $canvas.attr('width',w);
    $canvas.attr('height',h);
    this.width = w-this.shadow_size*2;
    this.height = h-this.shadow_size*2;
	this.position = this.element.css('position');
	$canvas.css(this.element.position());
	var background = (!this.gradient_color) ? 'background-color:'+this.area_color : null;
	this.element.wrapInner($('<div style="position:static;">'));
	
    this.draw();
}

var checkResize = function(object, force) {
    var $canvas = $(object.canvas);
    var w = object.element.outerWidth();
    var h = object.element.outerHeight();
    var x = object.element.offset().left;
    var y = object.element.offset().top;
    
    if (force || object.width != w-object.shadow_size*2 || object.height != h-object.shadow_size*2 ||
	        $canvas.offset().top != y || $canvas.offset().left != x) {
        pollCounter = 10;
        $canvas.css(object.element.position());
		object.width = w-object.shadow_size*2;
		object.height = h-object.shadow_size*2;
        //alert(($canvas.offset().left-object.shadow_size+object.area_padding)+"="+x);
		$canvas.attr('width',w);
		$canvas.attr('height',h);
		object.draw();
    }
};

var checkAllResize = function(force) {
    $.each(canvasElements, function() { checkResize(this, force); });
};

var pollCounter = 0;
var poll = function(){
    pollCounter--;
	checkAllResize();
    if (pollCounter <= 0) {
		pollCounter = 0;
		setTimeout(poll, 1000);
    } else {
		setTimeout(poll, 100);
    }
};
poll();

styleCanvas.prototype.width = 0;
styleCanvas.prototype.height = 0;
styleCanvas.prototype.area_radius = 5; // px
styleCanvas.prototype.area_color = '#ffffff'; // hex
styleCanvas.prototype.area_padding = 0; // px
styleCanvas.prototype.shadow_color = '0,0,0'; // rgb values
styleCanvas.prototype.shadow_opacity = 0.75; // 0-1
styleCanvas.prototype.shadow_size = 5; // px
styleCanvas.prototype.shadow_x_offset = 0; // px
styleCanvas.prototype.shadow_y_offset = 0; // px
styleCanvas.prototype.border_width = 0; // px
styleCanvas.prototype.border_color = '#000000'; // hex
styleCanvas.prototype.border_position = 'outside'; // 'outside', 'inside', 'center'
styleCanvas.prototype.gradient_color = false; // hex
styleCanvas.prototype.draw = function() {
    if (this.canvas.getContext) {
        var w = this.width;
        var h = this.height;
        var r = this.area_radius;
        var a_c = this.area_color;
        var c = this.shadow_color;
        var o = this.shadow_opacity;
        var s = this.shadow_size;
        var x = this.shadow_x_offset;
        var y = this.shadow_y_offset;
        var b_w = this.border_width;
        var b_c = this.border_color;
        var b_p = this.border_position;
		var g_c = this.gradient_color;
        var ctx = this.ctx;
        
        if (r==0) {r = .01;}
		
		ctx.fillStyle = '#ffffff';
		
        // shadow
        ctx.globalAlpha = o;
        ctx.lineWidth = 1.5;
        
        for (i=0;i < (s+r+(s/3));i++) {
			ctx.strokeStyle = 'rgba('+c+','+((.1/(s-(i/2)))*(i*1.5))+')';
            ctx.beginPath();
            ctx.arc(s+r+x+(s/3), s+r+y+(s/3), r+s-i+(s/3), pi, pi/2*3, false); // top left
            ctx.arc(s-r+w+x-(s/3), s+r+y+(s/3), r+s-i+(s/3), pi/2*3, pi*2, false); // top right
            ctx.arc(s-r+w+x-(s/3), s-r+h+y-(s/3), r+s-i+(s/3), 0, pi/2, false); // bottom right
            ctx.arc(s+r+x+(s/3), s-r+h+y-(s/3), r+s-i+(s/3), pi/2, pi, false); // bottom left
            ctx.closePath();
			ctx.stroke();
        }
        
        // area
        ctx.globalAlpha = 1;
        ctx.fillStyle = a_c;
        
        ctx.beginPath();
        ctx.arc(s+r, s+r, r, pi, pi/2*3, false); // top left
        ctx.arc(s-r+w, s+r, r, pi/2*3, pi*2, false); // top right
        ctx.arc(s-r+w, s-r+h, r, 0, pi/2, false); // bottom right
        ctx.arc(s+r, s-r+h, r, pi/2, pi, false); // bottom left
        ctx.fill();
        
        // gradient
		if (this.gradient_color) {
	        var lingrad = ctx.createLinearGradient(s,s-r+h-35,s,s+h);
	        lingrad.addColorStop(0, a_c);
	        lingrad.addColorStop(1, g_c);
	        ctx.fillStyle = lingrad;
	        
	        ctx.beginPath();
	        ctx.moveTo(s+w, s-r+h-35);
	        ctx.arc(s-r+w, s-r+h, r, 0, pi/2, false); // bottom right
	        ctx.arc(s+r, s-r+h, r, pi/2, pi, false); // bottom left
	        ctx.lineTo(s, s-r+h-35);
	        ctx.fill();
		}
        
        // border
        if (b_w > 0) {
            var pos = 0;
            var rad = 0;
            if (b_p=='outside') {
                rad = (b_w/2);
            } else if (b_p=='inside') {
                pos = -1;
                rad = -(b_w/2)-1;
            }
            ctx.lineWidth = b_w;
            ctx.strokeStyle = b_c;
            ctx.beginPath();
            ctx.arc(s+r+pos, s+r+pos, r+rad, pi, pi/2*3, false); // top left
            ctx.arc(s-r+w-pos, s+r+pos, r+rad, pi/2*3, pi*2, false); // top right
            ctx.arc(s-r+w-pos, s-r+h-pos, r+rad, 0, pi/2, false); // bottom right
            ctx.arc(s+r+pos, s-r+h-pos, r+rad, pi/2, pi, false); // bottom left
            ctx.closePath();
            ctx.stroke();
        }
    }
}