AC.QuickTime.CircularController = Class.create();
Object.extend(AC.QuickTime.CircularController.prototype, AC.QuickTime.Controller.prototype);
Object.extend(AC.QuickTime.CircularController.prototype, {
    setProgressColor: function(color) {
            this._progressColor = color;
            this._rgbaProgressColor = this.makeRGBA(color.red, color.green, color.blue, color.alpha);
    },
    makeRGBA: function () {
        return "rgba(" + [].slice.call(arguments, 0).join(",") + ")";
    },
    clearFrame: function(ctx) {
        ctx.clearRect(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);
    },

    loadingAnimation: function(context, bars, center, innerRadius, size, color) {
	    var animating = true,
	        currentOffset = 0,
			barAngle = 360/bars,
            imagebuffer = null,
            PIBy180 = ( Math.PI/180 ),
            self = this;;

	    function drawBlock(ctx, barNo, offset){
	        ctx.fillStyle = self.makeRGBA(color.red, color.green, color.blue, (barNo+color.alpha)/(bars));	
			/*
				//Cool but not what I wanted!!
				ctx.beginPath();
			  	ctx.moveTo(0, 0);
				ctx.arc( -innerRadius, -innerRadius, innerRadius, PIBy180*(barAngle/2-5), PIBy180*(-barAngle/2-5), true); 
				ctx.arc( -innerRadius, -innerRadius, innerRadius+size.height, PIBy180*(barAngle/2-5), PIBy180*(-barAngle/2-5), false); 

				ctx.lineTo(size.width/2, size.height);
				ctx.lineTo(size.width/2, 0);
				ctx.closePath();
				ctx.fill();
			
			*/
			
			ctx.beginPath();
			//var radians = PIBy180*degrees;
			ctx.arc( 0, 0, innerRadius, PIBy180*-5, PIBy180*-25, true); 
			ctx.arc( 0, 0, innerRadius+size.height, PIBy180*-25, PIBy180*-5, false); 
			ctx.closePath();
			ctx.fill();
        
            
            /*
            var curbar = (offset+barNo) % bars,
                pos = calculatePosition(curbar);
                ctx.translate(pos.x, pos.y);
                   ctx.fillRect(-size.width/2, 0, size.width, size.height);
            */
	    }
	    function calculateAngle(barNo){
	        return 2 * barNo * Math.PI / bars;
	    }
	    function calculatePosition(barNo){
	        angle = calculateAngle(barNo);
	        return {
	            y: (innerRadius * Math.cos(-angle)),
	            x: (innerRadius * Math.sin(-angle)),
	            angle: angle
	        };
	    }
	    function draw(ctx, offset) {
	        self.clearFrame(ctx);
            if(!imagebuffer) {
                //if(typeof G_vmlCanvasManager === "undefined") imagebuffer = new Image();
                ctx.save();
                ctx.translate(center.x, center.y);
                // for(var i = 0; i<1; i++){
                for(var i = 0; i<bars; i++){
                    var curbar = (offset+i) % bars;
                    ctx.save();
                    ctx.rotate(calculateAngle(curbar));
                    drawBlock(context, i, offset);
                    ctx.restore();
                }
                if(imagebuffer) imagebuffer.src = ctx.canvas.toDataURL();
                ctx.restore();
                //clearFrame(ctx);
            }
            else {
                ctx.save();
                var angle = calculateAngle((offset % bars));
                   //ctx.translate(innerRadius*Math.cos(angle), -innerRadius*Math.sin(angle));
                   //ctx.translate(innerRadius+size.width*Math.cos(angle), innerRadius+size.height*Math.sin(angle));
                   //ctx.translate(100, 100);
                   ctx.translate((ctx.canvas.width/2), (ctx.canvas.height/2));
                   //ctx.moveTo((ctx.canvas.width/4), (ctx.canvas.height/4));

                ctx.rotate(angle);
                ctx.drawImage(imagebuffer,-(ctx.canvas.width/2),-(ctx.canvas.height/2),ctx.canvas.width, ctx.canvas.height);
                ctx.restore();
            }
	    }
	    	    var animation =  {
	        stop: function (){
	            this.animating = false;
                window.clearTimeout(this.animatingTimeout);
	            self.clearFrame(context);
	        },
	        start: function (){
	            this.animating = true;
	            this.nextAnimation(0);
	        },
            nextAnimation: function (){
                if (!this.animating) {
                    return;
                };
                currentOffset = (currentOffset + 1) % bars;
                draw(context, currentOffset);
                var self = this;
                if(this.animatingTimeout) window.clearTimeout(this.animatingTimeout);
                this.animatingTimeout = setTimeout(function(){self.nextAnimation();}, 100);
            }

	    };
        return animation;
    },
    superStartLoadingIndicator: AC.QuickTime.CircularController.prototype._startLoadingIndicator,
    _startLoadingIndicator: function(movie) {
        this.superStartLoadingIndicator(movie);
        var self = this;
        this.launchLoadingAnimation();
    },
    superStopLoadingIndicator: AC.QuickTime.CircularController.prototype._stopLoadingIndicator,
    _stopLoadingIndicator: function(movie)
    {
        this.superStopLoadingIndicator(movie);
        this._loadingAnimation.stop();
    },

    launchLoadingAnimation: function() {
        //Now that controls are in the dom, we assume they are square of course. We're going to leave a margin of 10% around the loading annimation
        var controlRadius = this._controlRadius ? this._controlRadius : (this._controlRadius = this.playControl.clientWidth/2),
            controllerRadius = this._controllerRadius ? this._controllerRadius : (this._controllerRadius = this.controllerPanel.clientWidth/2),
            loadingAnimationAvailableHeight = (controllerRadius - controlRadius),
            animationHeight = loadingAnimationAvailableHeight*0.60,
            animationInnerRadius = controlRadius + (loadingAnimationAvailableHeight*0.08),
            canvas = this._animationCanvas;
            
            //console.log("controlRadius = "+controlRadius+", controllerRadius = "+controllerRadius+", animationHeight = "+animationHeight+", animationInnerRadius = "+animationInnerRadius);
            
          canvas.width = canvas.clientWidth;
	      canvas.height = canvas.clientHeight;
	      canvas.style.cssText="background:#transparent; position: absolute";
          //canvas.style.left = ""+(-1*(canvas.width - this.controllerPanel.clientWidth) / 2 ) + canvas.offsetLeft +"px";
          //canvas.style.top = ""+(-1*(canvas.height - this.controllerPanel.clientHeight) / 2 )+ canvas.offsetTop +"px";
          
        this.setProgressColor({red: 50, green: 50, blue: 51, alpha: 0.8});
	      this._loadingAnimation = this.loadingAnimation(canvas.getContext("2d"), 12, {x:(canvas.width/2), y:(canvas.height/2)}, animationInnerRadius, {width: 4, height: animationHeight}, this._progressColor);
          this._loadingAnimation.start();

    },
    render: function(containerId)
    {
        
        if (typeof containerId !== "undefined" && !$(containerId)) {
            throw new Error("Specified container ID, '" + containerId + "' not found in DOM");
        }

        this.controllerPanel = $(document.createElement('div'));
        Element.addClassName(this.controllerPanel, 'ACQuicktimeCircularController panel');
        
        this.controllerPanel.appendChild((this._animationCanvas = document.createElement("canvas")));
        
        if (typeof G_vmlCanvasManager !== "undefined") {
            this._animationCanvas = G_vmlCanvasManager.initElement(this._animationCanvas);
        }
        
        this.controllerPanel.appendChild((this._backroundElement = document.createElement("div")));
        Element.addClassName(this._backroundElement, 'ACQuicktimeCircularController');
        Element.addClassName(this._backroundElement, 'background');
        
        //TODO encapsulate button creation
        this.playControl = document.createElement('div');
        Element.addClassName(this.playControl, 'ACQuicktimeCircularController');
        Element.addClassName(this.playControl, 'control');
        Element.addClassName(this.playControl, 'play');
        this.playControl.innerHTML = 'Play';
        this.playControl.onclick = this.Play.bind(this);
        
        this.pauseControl = document.createElement('div');
        Element.addClassName(this.pauseControl, 'ACQuicktimeCircularController');
        Element.addClassName(this.pauseControl, 'control');
        Element.addClassName(this.pauseControl, 'pause');
        this.pauseControl.innerHTML = 'Pause';
        this.pauseControl.onclick = this.Stop.bind(this);

        //For Allowing IE Styling mainly..., so let's use the same everywhere
        var backgroundElement = document.createElement('div');
        Element.addClassName(backgroundElement, 'background');
        this.playControl.appendChild(backgroundElement);
        
        backgroundElement = document.createElement('div');
        Element.addClassName(backgroundElement, 'background');
        this.pauseControl.appendChild(backgroundElement);



        var playing = false;

        if(null !== this.movie) {
            playing = this.GetAutoPlay();
        }

        this.currentControl = (playing) ? this.pauseControl : this.playControl;
        this.controllerPanel.appendChild(this.currentControl);
        

    /*
        this.sliderPanel = document.createElement('div');
        Element.addClassName(this.sliderPanel, 'sliderPanel');

        this.track = document.createElement('div');
        Element.addClassName(this.track, 'track');
        this.sliderPanel.appendChild(this.track);

        this.loadedProgress = document.createElement('div');
        Element.addClassName(this.loadedProgress, 'loadedProgress');
        this.track.appendChild(this.loadedProgress);

        this.trackProgress = document.createElement('div');
        Element.addClassName(this.trackProgress, 'trackProgress');
        this.track.appendChild(this.trackProgress);

        this.playHead = document.createElement('div');
        Element.addClassName(this.playHead, 'playHead');
        this.track.appendChild(this.playHead);

        this.controllerPanel.appendChild(this.sliderPanel);

        this.timeDisplay = document.createElement('div');
        Element.addClassName(this.timeDisplay, 'timeDisplay');

        this.controllerPanel.appendChild(this.timeDisplay);
        
        */

        if (containerId) {
            $(containerId).appendChild(this.controllerPanel);

            if (this.delegate && typeof this.delegate.didRenderController === "function") {
                this.delegate.didRenderController(this);
            }

            this._eventSource.fire("QuickTime:didRenderController", {controller: this});

            if (this.movie) {
                this.monitorMovie();
            }
        }

        return this.controllerPanel;
    },
    	drawPlayingProgress : function(newTime, duration) {
		// OPTIMISATIONS:
		// - 0.5px trick for anti-aliasing,
		// - only draw the darkcolor area.
		// - transparent bckgnd.
		//debugger;
	    var ctx = this._animationCanvas.getContext("2d"),
	    	cx = r = ctx.canvas.width/2;
        
        //This smooth out the rendering of the circle in Safari and Firefiox. In IE it causes issues in the compatibility layer and looks great without
        if (!AC.Detector.isIEStrict()) {
            ctx.canvas.width = 2*ctx.canvas.clientWidth;
            ctx.canvas.height = 2*ctx.canvas.clientHeight;
        }
        if(newTime === duration) {
	        this.clearFrame(ctx);
            
        }
        else {

            var startangle = -Math.PI / 2, 
                endangle = startangle + ((newTime/duration) * Math.PI * 2);

            ctx.beginPath();
            ctx.moveTo(cx, cx);
            ctx.arc(cx, cx, r, startangle, endangle, false); 
            ctx.closePath();

            ctx.strokeStyle = ctx.fillStyle = this._rgbaProgressColor;
            ctx.fill();
            ctx.stroke();
        
        }
		
	},
    
    superDidPlayProgress: AC.QuickTime.CircularController.prototype._didPlayProgress,
    _didPlayProgress: function(newTime, duration) {
    
        //Update canvas playing progress
        this.drawPlayingProgress(newTime, duration);
        this.superDidPlayProgress(newTime, duration);
    
    },

    
    updateController: function(loaded)
    {
        if (!this.controllerPanel) {
            return;
        }

        //this._updateControllerLoadedProgress();

        // Ensure we don't stop updating while jogging
        // Also make sure we update if we're at the end of the movie, even if we're no long playing
        if (this.isJogging || this.isPlaying()) {

            var oldTime = this.currentTime,
                newTime = this.GetTime(),
                duration = this.GetDuration();

            if (!isNaN(oldTime) && !isNaN(newTime) && oldTime !== newTime) {
            
                this._didPlayProgress(newTime, duration);
            }
        }
    },

    monitorMovie: function()
    {
        if (!this.movie) {
            throw new Error("Cannot begin monitoring until attached to a movie");
        }

        this.state.monitorMovie.call(this);
        
        //Start the indetertminate progress animation
        


        this._hasBegunMonitoring = true;
    },
    super_attach: AC.QuickTime.Controller.prototype._attach,
    _attach: function(movie) {
		this.super_attach(movie);
		
		if(this._shouldStop) {
			this.Stop();
			this._shouldStop = false;
		}
	},

    superPlay: AC.QuickTime.Controller.prototype.Play,
    Play: function()
    {
	    // Movie started playing, show the pause control
	    if (this.controllerPanel) {
	        this.controllerPanel.replaceChild(this.pauseControl, this.currentControl);
	        this.currentControl = this.pauseControl;
	    }
		var self = this;
		this._shouldStop = false;
		self.superPlay();
        //setTimeout(function(){self.superPlay();},0);
	},
    Stop: function()
    {
        if (null !== this.movie) {
            try {
                this.movie.Stop();

				// Movie stopped playing, show the play control
		        if (this.controllerPanel) {
		            this.controllerPanel.replaceChild(this.playControl, this.currentControl);
		            this.currentControl = this.playControl;
		        }
		        this.Rewind();
				this.reset();
            } catch(e) {}
        }
		else {
			this._shouldStop = true;
		}
    },

    superReset: AC.QuickTime.Controller.prototype.reset,
    reset: function() {
        this.superReset();
        this._didPlayProgress(this.GetDuration(), this.GetDuration());
        //this.clearFrame(this._animationCanvas.getContext("2d"));
    },
    
    superattachToMovie: AC.QuickTime.Controller.prototype.attachToMovie,
    attachToMovie: function(movie, options) {
        this.superattachToMovie(movie, options);
    },

    GetTime: function()
    {

        var actualTime = null;
        try {
            //IE sometimes throws an error on accessing this property on first load
            if (this.movieIsVideo) {
                actualTime = this.movie.currentTime;
            } else {
                actualTime = this.movie.GetTime();
            }
        } catch (e) {
            //ignore error
        }

        if (null === actualTime) {
            //if we can't talk ot the plugin directly, estimate what time should be
            actualTime = this.currentTime + this._monitorDelay;
        } else {
            this.currentTime = actualTime;
        }

        return actualTime;
    }

    
});

/*
_importCSSFor("ProgressIndicator");

function initProgressIndicatorsInPage(){	
	var ProgressIndicatorsInPage = $$('.progressIndicator');
	var ProgressIndicators = [];
	for (var i=0; i < ProgressIndicatorsInPage.length; i++) {
		var newProgressIndicator = new ProgressIndicator().initFromDOM(ProgressIndicatorsInPage[i]);
		ProgressIndicators.push(newProgressIndicator);
	}
}


ProgressIndicator = function(){};

ProgressIndicator.prototype = {
	initFromScript : function(something){
		// Your code here...
		return this;
	},
	
	initFromDOM : function(progressIndicatorElement){
		this.DOMelement = progressIndicatorElement;
		this.isSmall = this.DOMelement.hasClassName('small');		
	   	this.progress = 0;
        
		this.timer = setInterval(this.incrementProgress, 30, this);
		return this;
	},
	
	incrementProgress : function(self){
		self.progress += 0.01;
		if(self.progress >= 1.0)
			self.progress = 0;
		self.drawLoadingPieChart();
	},
	
	drawLoadingPieChart : function() {
		// Aqua Metrics:
		// - Mini: fits in a 16x16 square,
		// - Regular: fits in a 32x32 square.
		// OPTIMISATIONS:
		// - 0.5px trick for anti-aliasing,
		// - only draw the darkcolor area.
		// - transparent bckgnd.
		
	    var ctx = this.DOMelement.getContext("2d"),
	    	darkColor = "rgb(138, 164, 206)",
	    	lightColor = "rgb(228, 241, 251)",
	    	cx = this.isSmall ? 8 : 16,
	    	r = this.isSmall ? 7 : 15;
        
	    ctx.beginPath();
	    ctx.arc(cx, cx, r, 0, Math.PI * 2, false); 
	    ctx.closePath();

	    ctx.lineWidth = 1;
	    ctx.strokeStyle = darkColor;
	    ctx.fillStyle = lightColor;
	    ctx.fill();
	    ctx.stroke();

	    var startangle = -Math.PI / 2;
	    var endangle = startangle + (this.progress * Math.PI * 2);

	    ctx.beginPath();
	    ctx.moveTo(cx, cx);
	    ctx.arc(cx, cx, r, startangle, endangle, false); 
	    ctx.closePath();

	    ctx.fillStyle = darkColor;
	    ctx.fill();
		
	}
};

*/


