// Copyright (c) 2009, Braydon Fuller

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
// 02110-1301, USA.

function dir(object){
    methods = [];
    for (z in object) if (typeof(z) != 'number') methods.push(z);
    return methods.join(', ');
}


function addEvent( obj, type, fn ) {
    if ( obj.attachEvent ) {
        obj['e'+type+fn] = fn;
        obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
        obj.attachEvent( 'on'+type, obj[type+fn] );
    } else
        obj.addEventListener( type, fn, false );
}

function GetWidth(){
    if (self.innerHeight){
        return self.innerWidth;
    } else if (document.documentElement && document.documentElement.clientHeight){
        return document.documentElement.clientWidth;
    } else if (document.body){
        return document.body.clientWidth;
    } else {
        return null;
    }
    return x;
}

function GetHeight(){
    if (self.innerHeight){
        return self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight){
        return document.documentElement.clientHeight;
    } else if (document.body){
        return document.body.clientHeight;
    } else {
        return null;
    }
}

function Audio(params){
    this.nativeAudio = false
    this.element = false
    this.audio = false
    this.safari = false
    this.controller = false
    this.widths = [480, 640]

    function bool(b) { if (b) return 1; return 0;}
    function hq(s) { return '"' + hx( s ) + '"';}
    function hx(s){
        if ( typeof s != 'String' ) { s = s.toString() }
        return s.replace( /&/g, '&amp;' )
            . replace( /</g, '&lt;' )
            . replace( />/g, '&gt;' );
    }

    function hasattr(elem,attr) {
	var isset;
	try {
	    eval("isset=typeof elem."+attr+"!='undefined';");
	} catch (e) {
	    isset=false;
	}
	return isset;
    }
    function dir(ob){
	var a=[],attr
	for(attr in ob){a.push(attr)}
	return a.sort().join(' ')
    }

    // Detect <video> element, and supported API
    this.detect = function() {
	// 'object' for Firefox & Safari, and 'function' for Opera
	if ( typeof HTMLAudioElement == 'object' || 
	     typeof HTMLAudioElement == 'function'){
	    hve = document.createElement('audio');
	    // check to see if we have the needed API, at some
	    // point this should support a wider range
	    if(hasattr(hve, 'currentTime') && hasattr(hve, 'play') && 
	       hasattr(hve, 'pause') && hasattr(hve, 'duration') && 
	       hasattr(hve, 'volume')) {
		this.nativeAudio = true;
	    }

	}

        // Check to see if the browser is Safari                                                                                                                                                          
        var a = navigator.userAgent.toLowerCase(), b=false
        var safari = a.match(/safari/)
        var chrome = a.match(/chrome/)
        if(safari && !chrome) this.safari = true

    }
    this.attributionTag = function(params, align){
        return '<p id="'+params.id+'_info" class="foxyaudioinfo" style="margin-top:0;width:'+params.size[0] +'px;font-family:'+params.display.font_family+';font-size:'+params.display.font_size+'px;"><span style="float:left;margin-top:6px;"><a href="'+params.display.audio_url+'">'+params.display.site_title+' / '+ params.display.audio_title +' </a></span><a href="http://www.vtechphones.com/?utm_source=Music%2BBlog%20Video&utm_medium=banner&utm_content=Music%2BBlog%20Video&utm_campaign=Blogvideo-vtechlogolink"><img src="'+params.display.site_url+'/wp-content/plugins/foxyvideo/player/vtechlogo-sm.png" style="float:'+align+';border:0;"></a><br style="clear:both;"></p>';
    }
    // Insert <audio> element
    this.embedAudioElement = function(elm, params, width, height) {
        var poster = params.base_url + 'cover' + "/" + params.base_file + ".jpg"
        var eid = params.id + "_embed"
	var vid = params.id + "_v"
	var cid = params.id + "_vc"
	var pid = params.id + "_p"
	var form_name = params.id + "_form"
        var ebid = params.id + "_embedbutton"
	var poster_html = '<img id=' + hq(pid) + 'src=' + hq(poster) + ' style="position:absolute;top:0;left:0;z-index:2">'
        var object_embed = '<object type="text/html" data="' + params.display.object_url + '" style="width:' + params.embed_size[0] + 'px;height:' + params.embed_size[1] + 'px;overflow:hidden;"></object>' + this.attributionTag(params, 'right');
        object_embed = object_embed.replace(/"/g,'&#34;')
        object_embed = object_embed.replace(/</g,'&lt;')
        object_embed = object_embed.replace(/>/g,'&gt;')
        var flash_embed = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="' + params.embed_size[0] + '" height="' + params.embed_size[1] + '"><param name=movie value="' + params.flash + '"><param name=quality value="high"><param name="wmode" value="transparent"><param name=FlashVars value="autoplay=false&width=' + params.embed_size[0] + '&height=' + params.embed_size[1] + '&embed_width=' + params.embed_size[0] + '&embed_height=' + params.embed_size[1] + '&base_url=' + params.base_url + '&base_file=' + params.base_file + '&audio_title=' + params.display.audio_title + '&audio_url=' + params.display.audio_url + '&site_title=' + params.display.site_title + '&site_url=' + params.display.site_url + '&bgcolor=' + params.bgcolor + '&object_url=' + params.display.object_url + '&font_size=' + params.display.font_size + '&font_family=' + params.display.font_family + '&flash_url=' + params.flash + '"><param name=bgcolor value="' + params.bgcolor + '"><embed src="' + params.flash + '" FlashVars="autoplay=false&width=' + params.embed_size[0] + '&height=' + params.embed_size[1] + '&embed_width=' + params.embed_size[0] + '&embed_height='+ params.embed_size[1] +'&base_url=' + params.base_url + '&base_file=' + params.base_file + '&audio_title=' + params.display.audio_title + '&audio_url=' + params.display.audio_url + '&site_title=' + params.display.site_title + '&site_url=' + params.display.site_url + '&bgcolor=' + params.bgcolor + '&object_url=' + params.display.object_url + '&font_size=' + params.display.font_size + '&font_family=' + params.display.font_family + '&flash_url=' + params.flash + '" quality="high" bgcolor="' + params.bgcolor + '" width="' + params.embed_size[0] + '" height="'+ params.embed_size[1] +'" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" wmode="transparent"></embed></object>' + this.attributionTag(params, 'left');
        flash_embed = flash_embed.replace(/"/g,'&#34;')
        flash_embed = flash_embed.replace(/</g,'&lt;')
        flash_embed = flash_embed.replace(/>/g,'&gt;')
        var input_style = 'style="border:1px solid #eee; margin-top:1%; background-color:#eee;font-color:#000;font-size:' + ( params.display.font_size * 1.3 ) + 'px;'

	var html = '<div style="position:relative;background-color:#'+params.bgcolor+'">' + poster_html + '<canvas id=' + hq( cid ) +
	    ' width=' + hq( width ) +
	    ' height="28" style="position:absolute;top:'+ (height - 28) +
	    'px;left:0;z-index:3;"></canvas>' +
            '<div id="' + eid + '" style="display:none;font-family:' + params.display.font_family + ';font-size:'+params.display.font_size+'px;position:absolute;background-color:#999;color:#fff;text-align:center;top:0;left:0;z-index:4;width:' + width + 'px;height:'+(height-28)+'px;opacity:0.9;">' + 
            '<form name="' + form_name + '">' +
            '<div style="margin-top:5%;" onclick="document.' + form_name + '.allcode.focus();document.' + form_name + '.allcode.select();"><strong>HTML 5 Audio or Flash</strong> <em>(for your domain)</em><br><input name="allcode" type="text" ' + input_style + 'width:50%;" value="' + object_embed + '"></input></div>' +
            '<div style="margin-top:5%;" onclick="document.' + form_name + '.flashcode.focus();document.' + form_name + '.flashcode.select();"><strong>Flash</strong> <em>(for social networks)</em><br><input name="flashcode" type="text" ' + input_style + 'width:70%;" value="' + flash_embed + '"></input></div>' +
            '<div style="margin-top:5%;" onclick="document.' + form_name + '.urlcode.focus();document.' + form_name + '.urlcode.select();"><strong>URL</strong> <em>(for email, microblogs, and chat)</em><br><input name="urlcode" type="text" ' + input_style + 'width:30%;" value="' + params.display.audio_url + '"></input></div>' +
            '</form>' +
            '</div>' +
            '</div>';
	elm.innerHTML = html
    }

    // Insert Audio
    this.init = function(params) {

	this.detect()
	this.element = document.getElementById(params.id)

        // Safari workaround, playback of video larger than 320 px wide has poor playback                                                                                                                 
        // Dec 8, 2009, latest Safari version 4.0.3                                                                                                                                                       
        if (this.safari) {
            var vid = this.element.getElementsByTagName("audio")[0];
            this.element.innerHTML = vid.innerHTML.replace(/<source(.*)>/g,"");
        }

	if (this.nativeAudio && !this.safari){

            var width = params.size[0]
            var height = params.size[1]

            this.embedAudioElement(this.element, params, width, height)
	    this.audio = document.getElementById(params.id+"_v")
	    this.controller = new AudioController(params, width, height)

            this.element.style.width = width+"px"
            this.element.width = width
            this.element.style.height = height+"px"
            this.element.height = height
	} 


    }
    if (params){
        this.init(params)
    }
};

function AudioController(params, width, height){
    var duration = 100, time = 1, progress = 1, muted = false, scrub = null,
    tbx = null, tbw = null, cint = null, params = params, audio = null,
    element = null, wrapper = null, poster = null, playing = true;

    var drawhbar = function(ctx,w,h,xs,ys,rgba){
	var bxd = w          //bar x distance
	var bxs = xs         //bar x start
	var bxe = bxs+bxd    //bar x end
	var bys = ys         //bar y start
	var bye = ys+h       //bar y end
	ctx.fillStyle = rgba
	ctx.beginPath()
	ctx.moveTo(bxs+4, bys)
	ctx.lineTo(bxe-4, bys)
	ctx.bezierCurveTo(bxe-4, bys, bxe, bys, bxe, bys+4)
	ctx.bezierCurveTo(bxe, bys+4, bxe, bye, bxe-4, bye)
	ctx.lineTo(bxs+4, bye)
	ctx.bezierCurveTo(bxs+4, bye, bxs, bye, bxs, bys+4)
	ctx.bezierCurveTo(bxs, bys+4, bxs, bys, bxs+4, bys)
	ctx.closePath()
	ctx.fill()
    }
    var drawvbar = function(ctx,w,h,x,y,c){
	ctx.fillStyle = c
	ctx.beginPath()
	var r=w/2,xr=x+r,xw=x+w,yh=y+h,yhr=yh-r,yr=y+r
	ctx.beginPath()
	ctx.moveTo(xr,y);ctx.bezierCurveTo(xr,y,xw,y,xw,yr);ctx.lineTo(xw,yhr)
	ctx.bezierCurveTo(xw,yhr,xw,yh,xr,yh);ctx.bezierCurveTo(xr,yh,x,yh,x,yhr)
	ctx.lineTo(x,yr);ctx.bezierCurveTo(x,yr,x,y,xr,y)
	ctx.closePath()
	ctx.fill()
   }
   var drawplay = function(ctx,on,x,y,c){
	ctx.save()
	ctx.translate(x,y)
	ctx.fillStyle=c;
	switch (on) {
	case true:
	    ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(0,12);
	    ctx.lineTo(4,12);ctx.lineTo(4,0);ctx.closePath();ctx.fill()
	    ctx.beginPath();ctx.moveTo(7,0);ctx.lineTo(7,12);
	    ctx.lineTo(11,12);ctx.lineTo(11,0);ctx.closePath();ctx.fill()
	    break;
	case false:
	    ctx.beginPath()
	    ctx.moveTo(0,0);ctx.lineTo(9,6);ctx.lineTo(0,12);
	    ctx.closePath();ctx.fill();
	    break;
	}
	ctx.restore()
    }
    var drawvolume = function(ctx,m,x,y,c){
        ctx.save()
	ctx.fillStyle = c
	var yf=y+4,yt=y+11,xe=x+8,xt=x+3
	ctx.beginPath()
	ctx.moveTo(x, yf);ctx.lineTo(x, yt);ctx.lineTo(xt, yt)
	ctx.lineTo(xe, y+15);ctx.lineTo(xe, y);ctx.lineTo(xt, yf)
	ctx.closePath(); ctx.fill()
	if (!m) {
	    ctx.beginPath(); ctx.strokeStyle = c; ctx.lineWidth = 2
	    x=x+10,y=y+4; ctx.moveTo(x,y)
	    ctx.bezierCurveTo(x,y,x+5,y+2.7,x,y+7)
	    ctx.stroke()
            ctx.closePath()
	}
        ctx.restore()
    }
    var embedimg = new Image()
    embedimg.src = params.base_url + 'share.png'
    var drawembed = function(ctx,x,y,c){
        ctx.save()
        ctx.drawImage(embedimg, x+24, y-1)
        ctx.strokeStyle = c
        ctx.lineWidth = 2
        ctx.beginPath()
        ctx.moveTo(x+5,y)
        ctx.lineTo(x, y+4.5)
        ctx.lineTo(x+5,y+9)
        ctx.moveTo(x+12,y-2)
        ctx.lineTo(x+8,y+11)
        ctx.moveTo(x+15, y)
        ctx.lineTo(x+20, y+4.5)
        ctx.lineTo(x+15, y+9)
        ctx.stroke()
        ctx.closePath()
        ctx.restore()
    }
    var drawscrub = function(ctx,x,y){
	drawvbar(ctx,11,20,x-4,y,"rgba(255,255,255,1)")
	drawvbar(ctx,7,16,x-2,y+2,"rgba(70,70,70,1)")
    }
    var drawtime = function (ctx,x,y,w){
	drawhbar(ctx,w,8,x,y,"rgba(154,154,154,0.8)")
	drawhbar(ctx,progress/100*w,8,x,y,"rgba(200,200,200,0.8)")
	drawhbar(ctx,time/duration*w,8,x,y,"rgba(255,255,255,1)")
    }
    var draw = function (ctx,w,h){
	ctx.clearRect(0,0,w,h);
	ctx.save();
	ctx.translate(0,h-28)
	ctx.fillStyle = "rgba(20,20,20, 0.7)"
	ctx.fillRect (0,0,w,28)
	tbw = w-140
	tbx = 28
        drawtime(ctx,tbx,10,tbw)
	scrub = (time / duration * tbw) + tbx
        drawscrub(ctx,scrub,4)
        playing = true
// 	if(audio){
//             if (audio.paused) {
// 	        playing = false
// 	    } 
//         } else {
//             playing = false
//         }
	if(audio){
            if (audio.paused) {
	        playing = false
	    } 
        } else {
            playing = false
        }
	drawplay(ctx,playing,10,8,"rgba(255,255,255,1)");
	drawvolume(ctx,muted,w-100,6,"rgba(255,255,255,1)")
	drawembed(ctx,w-75,9.5,"rgba(255,255,255,0.8)")
	ctx.restore();
    }
    var clear = function(ctx,w,h) {
	ctx.clearRect(0,0,w,h);
    }
    var mouseout = function() {
	var c = element
	var ctx = c.getContext("2d")
	var w = c.width, h = c.height
	if(playing){
            clear(ctx,w,h)
	    clearInterval(cint)
        };
	c.removeEventListener('mousemove', scrubber, false)
    }
    var mousedown = function (ev) {
        t = this.parentNode.parentNode
	var c = element
	var x = ev.layerX - c.offsetLeft
	var y = ev.layerY - c.offsetTop
	var w = c.width
	var h = c.height
	if (x <= 28){
	    if(playing){pause();}else{play();}
	} else if (x >= w-110 && x <= w-81){
	    if(muted){unmute();}else{mute();}
	} else if (x >= w-80){
            var embstage = document.getElementById(params.id + "_embed");
            if(embstage.style.display == "none"){
                embstage.style.display="block"
            } else {
                embstage.style.display="none"
            }
	} else if (x >= scrub-4 && x <= scrub+8){
	    c.addEventListener('mousemove', scrubber, false)
	} else {
	    var s = Math.round((x - tbx) / tbw * duration)
	    if (s > duration) s = duration
	    if (s < 0) s = 0
	    seek(s)
	}
	var ctx = c.getContext("2d");
	clear(ctx,w,h);
	draw(ctx,w,h);
    }
    var mouseup = function(ev){
	var c = element
	c.removeEventListener('mousemove', scrubber, false)
    }
    var scrubber = function(ev) {
	var c = element
	var x = ev.layerX - c.offsetLeft;
	var s = Math.round((x - tbx) / tbw * duration)
	if (s > duration) s = duration
	if (s < 0) s = 0
	seek(s)
    }
    var updateprogress = function(ev){
	if (ev.lengthComputable) {
	    if (ev.total != 0){
		progress = notzero(Math.round(ev.loaded/ev.total*100),1)
	    }
	    return;
	}
	if (ev.total) {
            progress = notzero((100*ev.loaded/ev.total).toFixed(0),1)
	}
	return;
    }
    var notzero = function(x,alt){
        if (x == 0 || x == '0'){
            return alt;
        }
        return x;
    }
    var updatetime = function() {
        if(!audio)
            return null;
        var v = audio
	var n = "" + Math.round(v.currentTime*10)/10;
	if (n.toString() == "NaN") {
	    time = 1;
	} else {
	    time = notzero(n,1);
	}
    }
    var updateduration = function() {
        if(!audio)
            return 100;
	var v = audio
	var n = Math.round(v.duration*10)/10;
	if (n.toString() == "NaN") {
	    duration = 100;
	  this.duration = 100;
	} else {
	    duration = notzero(n,100);
	    //this.duration = notzero(n,100);
	}
    }
    function audiotag(params, width, height){
        var sources = [[params.base_url + 'ogg' + "/" + params.base_file + ".ogg", "audio/ogg"],
                       [params.base_url + 'mp3' + "/" + params.base_file + ".mp3", "audio/mp3"]]
	var vid = params.id + "_v"
	var html = ''
	var autoplay_html = ''
	if (params.autoplay) {
	    autoplay_html = ' autoplay="true"'
	}
	html += '<audio id=' + hq( vid ) + ' width=' + hq( width ) + 
	        ' height=' + hq( height ) + autoplay_html + 
                ' style="position:absolute;top:0;left:0;z-index:1;" autobuffer="true">';

	for(var i=0,l=sources.length;i<l;i++){
	    html += '<source src=' + hq(sources[i][0]) +
		    ' type=' + hq(sources[i][1]) + '/>';
	}
	html += ' </audio>';
	return html;
    }
    function initaudio(params, width, height) {
        var newdiv = document.createElement('div')
        newdiv.innerHTML = audiotag(params, width, height)
	elm = document.getElementById(params.id).firstChild
        elm.appendChild(newdiv)
	var audio = document.getElementById(params.id + "_v")
	audio.addEventListener('loadedmetadata', updateduration, false)
	audio.addEventListener('durationchanged', updateduration, false)
	audio.addEventListener('timeupdate', updatetime, false)
	audio.addEventListener('progress', updateprogress, false)
        return audio
    }
    var play = function(){
        if(!audio){
            audio = initaudio(params, width, height)
            audio.addEventListener('canplaythrough', function(){audio.play();}, false)
        } else {
            audio.play()
        }
    }
    this.play = play
    var stop = function(){var v = audio;v.pause();v.currentTime = 0}
    this.stop = stop
    var pause = function(){audio.pause()}
    this.pause = pause
    var mute = function(){audio.volume = 0;muted = true}
    this.mute = mute
    var seek = function(t){audio.currentTime = t;}
    this.seek = seek
    var unmute = function(){audio.volume = 1;muted = false}
    this.unmute = unmute
    var drawcontroller = function(ev) {
        updateduration()
        updatetime()
	var c = element
	var ctx = c.getContext("2d")
	var w = c.width, h = c.height
	draw(ctx,w,h)
    }
    var mouseover = function(ev) {
	var c = element
	var ctx = c.getContext("2d")
	var w = c.width, h = c.height
	clearInterval(cint)
	cint = setInterval(drawcontroller, 20)
    }
    function hq(s) { return '"' + hx( s ) + '"';}
    function hx(s){
        if ( typeof s != 'String' ) { s = s.toString() }
        return s.replace( /&/g, '&amp;' )
            . replace( /</g, '&lt;' )
            . replace( />/g, '&gt;' );
    }
    this.init = function(params) {
        if (params.autoplay){
            audio = initaudio(params, width, height)
        }
	element = document.getElementById(params.id + "_vc")
	wrapper = document.getElementById(params.id)
	poster = document.getElementById(params.id + "_p")
	//wrapper.addEventListener('mouseover', mouseover, false)
	//wrapper.addEventListener('mouseout', mouseout, false)
	element.addEventListener('mousedown', mousedown, false)
	element.addEventListener('mouseup', mouseup, false)
	cint = setInterval(drawcontroller, 20)
    }
    this.init(params)
}
