$(function() {
    
    // canvas properties
    var canvas, context, cx, cy;
    canvas = $('canvas')[0];
    context = canvas.getContext("2d");
    cx = canvas.width/2;
    cy = canvas.height/2;
    
    // ArcClock properties
    var radius=100, thickness = 20, arcs = [], oArcs=[], tArcs=[], bgArcs=[];
    //var defaultData = {min0:-120, max0:120, min1:-120, max1:120, min2:-120, max2:120};
    var defaultData = {min0:-180, max0:120, min1:-150, max1:150, min2:-120, max2:180};
    var bgColors = ["rgb(210, 210, 210)", "rgb(230, 230, 230)", "rgb(250, 250, 250)"];
    var fgColors = ["rgb(50, 50, 50)", "rgb(100, 100, 100)", "rgb(150, 150, 150)"];
    //var fgColors = ["rgb(255, 211, 75)", "rgb(201, 83, 24)", "rgb(143, 36, 25)"];
    var currentDate, hours, minutes, seconds;
    var pi = Math.PI; // small performance improvement
    var tArc;
    for(var i=0; i<=2; i++){
        tArc = getArc(i, defaultData["min"+i], defaultData["max"+i], 100);
        bgArcs[i] = tArc;
    }
    
    // update ArcClock with time
    setInterval( function(){
        updateArcsData();
        animate();
    }, 1000 );
    
    // updateArcsData
    function updateArcsData(){
        currentDate = new Date();
        hours = currentDate.getHours();
        minutes = currentDate.getMinutes();
        seconds = currentDate.getSeconds();
        // calculate and store desired arcs data
        var min, max, perc, tArc;
        for(var i=0; i<=2; i++){
            if(i===0){   perc = hours/24*100; }
            if(i===1){   perc = minutes/60*100; }
            if(i===2){   perc = seconds/60*100; }
            tArc = getArc(i, defaultData["min"+i], defaultData["max"+i], perc);
            oArcs[i] = tArcs[i];
            tArcs[i] = tArc;
        }
    }
    
    // Animation called on every second
    var tween, info;
    TWEEN.start();
    function animate(){
        function update() {
            for(var i=0; i<=2; i++){
                arc = getArc(i, defaultData["min"+i], defaultData["max"+i], info["perc"+i]);
                arcs[i] = arc;
            }
            draw();
        }
        if(oArcs[0] === undefined){ info = {perc0: 0, perc1:0, perc2:0}; }else{ info = {perc0: oArcs[0].perc, perc1:oArcs[1].perc, perc2:oArcs[2].perc}; }
        tween = new TWEEN.Tween(info).to({perc0: tArcs[0].perc, perc1:tArcs[1].perc, perc2:tArcs[2].perc}, 600).easing(TWEEN.Easing.Exponential.EaseOut).onUpdate(update).start();
    }
    
    // drawing function called on every interval
    function draw(){
        // clear
        context.clearRect(0,0,canvas.width,canvas.height);
        // draw arcs
        var arc;
        for(var i=0; i<=2; i++){
            arc = bgArcs[i];
            if(arc !== undefined){
                context.beginPath();
                context.lineWidth = (i<2) ? thickness+1 : thickness; // hack that fixes the buggy gap between arcs when drawn together
                context.strokeStyle = bgColors[i];
                context.arc(cx, cy, radius+(thickness*i), arc.iniAngle, arc.endANgle, false);
                context.stroke();
            }
        }
        for(var i=0; i<=2; i++){
            arc = arcs[i];
            if(arc !== undefined){
                context.beginPath();
                context.lineWidth = (i<2) ? thickness+1 : thickness; // hack that fixes the buggy gap between arcs when drawn together
                context.strokeStyle = fgColors[i];
                context.arc(cx, cy, radius+(thickness*i), arc.iniAngle, arc.endANgle, false);
                context.stroke();
            }
        }
    }
    
    // Auxiliary functions functions
        function getArc(arc_no, min, max, perc){
            var maxArc = max-min;
            var increase = (maxArc*(perc/100));
            var endAngle = min+increase;
            var arc = {
                iniAngle: min*(pi/180), // to radians
                endANgle: endAngle*(pi/180),
                perc: perc
            };
            return arc;
        }
});
