//GLOBAL VARIABLES

var bookNumber;
var bookChapter;
var bookName;

var playingNext = false;
var playingPlaylist = false;
var chapterDuration;
var playlist;

/**
 *This function gets the reading plan selected from the drop down list and
 *retrieves today's daily Bible reading.
 */
function getReadingPlanReading(){

    var plan =document.getElementById("reading_plan").value;

    //every-day-in-the-word ;; same as the OneYear Bible
    //one-year-tract, through-the-bible, every-day-in-the-word, and bcp
    var http;
    var str="plan="+plan;

    http=GetHttpObject();
    var url="bible.php";

    http.onreadystatechange=function(){
        if (http.readyState==4 || http.readyState=="complete") {
            //alert(http.responseText);
            var xmlDoc = parseXML(http.responseText);
            queueDailyReading(xmlDoc);//send the returned xml to the queue
        }
    };
    http.open("POST",url,true);
    http.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
    http.send(str);
    return http;
}


/**
 *this function takes an xml document for todays Bible reading for a particular reading plan
 *and creates a playlist out of the passages and then calls the playPlaylist() function
 */
function queueDailyReading(xmlDoc){    
    var plan = xmlDoc.getElementsByTagName("plan")[0].childNodes[0].nodeValue;
    if(plan == "every-day-in-the-word"){
        var otReading = xmlDoc.getElementsByTagName("ot")[0].childNodes[0].nodeValue;
        var ntReading = xmlDoc.getElementsByTagName("nt")[0].childNodes[0].nodeValue;
        var psalmReading = xmlDoc.getElementsByTagName("psalm")[0].childNodes[0].nodeValue;
        var proverbReading = xmlDoc.getElementsByTagName("proverb")[0].childNodes[0].nodeValue;
        playlist = new Array(otReading, ntReading, psalmReading, proverbReading);    
    }
    //<family>Exodus 31; John 10</family><private>Proverbs 7; Galatians 6</private>
    if(plan == "one-year-tract"){
        var familyReading = xmlDoc.getElementsByTagName("family")[0].childNodes[0].nodeValue;
        var privateReading = xmlDoc.getElementsByTagName("private")[0].childNodes[0].nodeValue;
        var familyArray = familyReading.split(";");
        var privateArray = privateReading.split(";");
        playlist = familyArray.concat(privateArray);
    }
    //<morning>Joshua 1-3</morning><evening>Luke 1:57-80</evening>
    if(plan == "through-the-bible"){
        var morningReading = xmlDoc.getElementsByTagName("morning")[0].childNodes[0].nodeValue;
        var eveningReading = xmlDoc.getElementsByTagName("evening")[0].childNodes[0].nodeValue;
        playlist = new Array(morningReading,eveningReading);
    }
    if(plan == "bcp"){
        /*<info>
         *<psalm-1>Ps. 95,88</psalm-1>
         *<psalm-2>Ps. 91,92</psalm-2>
         *<ot>Jer. 11:1-8,14-20</ot>
         *<nt>Rom. 6:1-11</nt>
         *<gospel>John 8:33-47</gospel>
         *<liturgical>
         *  <season>Lent</season>
         *  <week>3 Lent</week>
         *</liturgical>
         *<raw>Ps. 95, 88; Ps. 91, 92; Jer. 11:1-8, 14-20; Rom. 6:1-11; John 8:33-47</raw></info>*/
        //var morningReading = xmlDoc.getElementsByTagName("morning")[0].childNodes[0].nodeValue;
        //var eveningReading = xmlDoc.getElementsByTagName("evening")[0].childNodes[0].nodeValue;
        //playlist = new Array(morningReading,eveningReading);
        alert('Plan not supported yet.');
        return;
    }
   
    playPlaylist();
}
/**
* playPlaylist() is a "destructive" function, i.e.
* it removes the first element in the list in order to play it
* thus subsequent calls to the function will play the new "top"
* of the queue
*/
function playPlaylist(){
    playingPlaylist = true;
    //alert(playlist);
    if(playlist.length > 0){
        var verseString = playlist.shift();//get the first reading as a Passage string
        verseString = verseString.trim();
        //alert(verseString);
        var passageArray = verseString.split(" ");//split it into an array
        var book =passageArray[0];//get the book string
        var verses =passageArray[1];//get the passage verses string

        playingNext = false; //should only play the requested passage and not any after it
        bookName = book;//set the global varible used in getReading()
        bookChapter = verses;//set the global variable used in getReading()
        //alert("verseString = "+verseString +" book= "+ book + " verses= "+verses);
        getReading();
    }
}
/**
 *Trim white space from both ends of string.
 */
String.prototype.trim=function(){
    return this.replace(/^\s*| \s*$/g,'');
}

/**
 * Using the global variables bookName and bookChapter this function
 * gets the Bible reading for the request from the ESV web-service
 * and places it in the text-target div.  It then calls the loadPlayer() function
 */
function getReading(){
    var http;
    var str="passage="+bookName+" "+bookChapter;

    http=GetHttpObject();
    var url="bible.php";

    http.onreadystatechange=function(){
        if (http.readyState==4 || http.readyState=="complete") {
            document.getElementById("glass_pane").style.display="none";
            document.getElementById("text_target").innerHTML=http.responseText;
            loadAudioPlayer();
        }
    };
    http.open("POST",url,true);
    http.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
    http.send(str);
    return http;
}

/**
 * This function gets the url of the mp3 for the Bible reading
 * and then hides the link in the text_target area so it can't be clicked.
 * It then destroys any previous sound objects in the soundManager
 * The function then creates a new sound object from the url,
 * adds event listeners to the object and starts the audio playing.
 */
function loadAudioPlayer(){
    var audioPlayer = document.getElementsByTagName("small")[0];
    if(audioPlayer == null){
        return;
    }
    var audioLink = audioPlayer.getElementsByTagName("a")[0];
    var verseString = audioLink.attributes['href'].value;

    //hide link
    hideAudioLink();

    //load the target for the mp3 into the player
    //register the event update() so that the player calls it when
    //the song is finished
    soundManager.destroySound('bible_mp3');

    var player = soundManager.createSound({
        id:'bible_mp3',
        url:  verseString,
        onfinish: function() {
            update();
        },
        onload: function(){
            chapterDuration = player.duration;
            var positionSeconds = (chapterDuration /1000) % 60;
            var positionMinutes = chapterDuration/ 1000 / 60 ;


            var minutes = parseInt(positionMinutes.toFixed(2));
            var seconds = parseInt(positionSeconds);

            var secondsString =""+seconds;
            if(secondsString.length < 2){
                secondsString = "0"+secondsString;
            }
            document.getElementById('total_time').innerHTML= minutes+":"+secondsString;
        },
        whileplaying: function(){
            updateProgress(player.position)
        }
    });

    // SM2 has loaded - now you can create and play sounds!
    document.getElementById('togPause').src="player/png/pause.png";
    player.play('bible_mp3');
}

/**
 * update() determines if the audio that just finished was from a "playingNext"
 * state or a playingPlaylist state, and then choses the proper record update method.
 */
function update(){
    if(playingNext){
        updateRecord(bookNumber, bookChapter);
    }else if(playingPlaylist){
        //playPlaylist() is a "destructive" function, i.e.
        //it removes the first element in the list in order to play it
        //thus subsequent calls to the function will play the new "top"
        //of the queue
        playPlaylist();
    }
}


/**
 * updateRecord() takes a bookId which is the zero based index of Bible books and a chapter
 * number for the most recently read chapter in that book.
 * This then makes a call to the database to update or create a record for that book
 * and how many chapters have been read in it.
 *
 * Then, depending if the play mode is, playingNext or playingPlaylist, it calls
 * the proper function to load the next reading.
 */
function updateRecord(bookId, read){
    bookId = Math.round(parseInt(bookId, 10));
    var xmlHttp;
    var str="book="+bookId+"&read=" + read;
    xmlHttp=GetHttpObject();
    var url="index.php";
    var continuous = document.getElementById("continuous").checked;
    xmlHttp.onreadystatechange=function(){
        if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
            document.getElementById("glass_pane").style.display="none";
            document.getElementById("txtHint").innerHTML=xmlHttp.responseText;            

            if(continuous && playingNext){
                playNext(bookNumber, bookName, bookChapter);
            }else if(playingPlaylist){
                playPlaylist();
            }else{
                return;
            }
        }
    };
    xmlHttp.open("POST",url,true);
    xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
    xmlHttp.send(str);
    return xmlHttp;
}



/**
 * takes a book number, book name and greatest chapter read so far
 * This function is a wrapper for getReading() so that it can be used abstractly
 * It sets global variables and flags so that when getReading() is called it will
 * get the next chapter after the greatest one read in the database
 */
function playNext(bookId, name, read){
    playingNext = true;
    var chapter = parseInt(read)+1;
    bookNumber = bookId;
    bookName = name;
    bookChapter = chapter;
    getReading();
}

/**
 * takes a Bible book name and chapter
 * called by clicking on a bar.
 * The function sets a flag so that only the chapter clicked will be retrieved
 * and played, and it will not automatically start playing the next chapter
 * when finished.
 */
function listen(book, chapter){
    playingNext = false; //should only play one chapter
    playingPlaylist = false;
    bookName = book;
    bookChapter = chapter;
    getReading();
}

var lastKnownSecond = 0;
/**
 * position is the position of the read head in milliseconds
 * this function is called by the listener attached to the sound
 * object at some regular interval.  It updates the progress
 * bar and the time elapsed in the gui.
 */
function updateProgress(position){
    var positionSeconds = (position /1000) % 60;
    var positionMinutes = position/ 1000 / 60 ;


    var minutes = parseInt(positionMinutes.toFixed(2));
    var seconds = parseInt(positionSeconds);
    //this next condition demands that the seconds are greater
    //than the last stored seconds. This is because the updateProgress
    //function gets called many times per second, and we do not want
    //to paint the screen everytime it is called, because most of the time
    //it is only repainting the same thing.
    //There was a large reduction in cpu usage when this line was added.
    //Since seconds is an integer, this function will only paint once per
    //second.
    
    if(seconds == lastKnownSecond){
        return;
    }
    lastKnownSecond = seconds;

    var secondsString =""+seconds;
    if(secondsString.length < 2){
        secondsString = "0"+secondsString;
    }

    var perc =   position / chapterDuration;
    perc = perc * 100;
    if(isNaN(perc)){
        return;
    }
    else{
        perc.toFixed(2);
        document.getElementById('time').innerHTML= minutes+":"+secondsString;
        document.getElementById('count').style.width=+" "+Math.round(perc)+"%";
    }
}
/**
 * position is the position of the read head in milliseconds
 * this function is called by the listener attached to the sound
 * object at some regular interval.  It updates the progress
 * bar and the time elapsed in the gui.
**COMMENTED OUT TO TEST NEW UPDATEPROGRESS ABOVE
function updateProgress(position){
    var positionSeconds = (position /1000) % 60;
    var positionMinutes = position/ 1000 / 60 ;


    var minutes = parseInt(positionMinutes.toFixed(2));
    var seconds = parseInt(positionSeconds);

    var secondsString =""+seconds;
    if(secondsString.length < 2){
        secondsString = "0"+secondsString;
    }

    var perc =   position / chapterDuration;
    perc = perc * 100;
    if(isNaN(perc)){
        return;
    }
    else{
        perc.toFixed(2);
        document.getElementById('time').innerHTML= minutes+":"+secondsString;
        document.getElementById('count').style.width=+" "+Math.round(perc)+"%";
    }
}
 */

/**
 * This function is called when a user clicks on the 5 / 25 chapter read out of
 * total chapter display to the right of the bars for a book.
 * It opens a prompt dialog asking for the number of chapters read.
 * The user enters a number and the function updates the database.
 *
 * If the user closes the dialog with no entry, no database call is made.
 * If the user puts in anything smaller than 1 it is zero
 * if the user puts in anything larger than the number of chapters
 * in the book, it is set to the max number of chapters.
 *
 */
function inputRead(bookId){
    var read = prompt("Enter number of Chapters read");
    if(read =="" || read ==null){
        return;
    }
    playingNext = false;
    updateRecord(bookId, read);
}

/**
 * This is the function called by clicking on the pause button
 * in the gui.
 */
function pausePlayer(){
    var playButton = document.getElementById('togPause');

    if(playButton.src.search("player/png/pause.png")>-1){
        playButton.src="player/png/play.png";
    }else{
        playButton.src="player/png/pause.png";
    }
    soundManager.togglePause('bible_mp3');
}

/**
 * This is the function called by clicking on the stop button in the gui.
 */
function stopPlayer(){
    var playButton = document.getElementById('togPause');

    if(playButton.src.search("player/png/pause.png")>-1){
        playButton.src="player/png/play.png";
    }
    soundManager.stop('bible_mp3');
}


/**
 * This is the function called when a user clicks on the progress bar of the auido
 * gui.  It calculates the percentage from the left edge of the progress bar of the
 * total width of the progress bar as the position in the total duration of the audio file
 * It then moves the audio play head to that location and plays the audio file.
 */
function seek(event){
    var lx = event.layerX;
    var width = document.getElementById('progress').style.width;
    var w = parseInt(width);
    var percent = (lx / w ).toFixed(4);
    var position = chapterDuration * percent;
    soundManager.setPosition('bible_mp3', position);
}


/**
 * helper method used to hide the link to the audio file in the Bible reading
 * so that the only interface to the audio is the player gui.
 */
function hideAudioLink(){
    var audioPlayer = document.getElementsByTagName("small")[0];
    if(audioPlayer == null){
        return;
    }
    audioPlayer.style.display="none";
}


/**
 * This is the function that is called when a user clicks on the "bigger" button
 * It displays the transparent black background and enlarges the Bible text reading
 * area.  Nothing is clickable behind the Text area.
 */
function maximize(){
    document.getElementById("frame_minimized").id="frame_maximized";
    document.getElementById("minimize_button").style.display="block";
    document.getElementById("maximize_button").style.display="none";
    document.getElementById("glass_pane").style.display="block";
}

/**
 * This is the function that is called when a user clicks on the "smaller" button
 * It hides the transparent black background and restors the Bible text reading
 * area to its original position.
 */
function minimize(){
    document.getElementById("frame_maximized").id="frame_minimized";
    document.getElementById("minimize_button").style.display="none";
    document.getElementById("maximize_button").style.display="block";
    document.getElementById("glass_pane").style.display="none";
}

/**
 * this  function takes an xml string and returns a Javascript xml DOM object
 */
function parseXML(xmlString){
    var xmlDoc;

    try{//Internet Explorer
        xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async="false";
        xmlDoc.loadXML(xmlString);
    }
    catch(e){
        try{ //Firefox, Mozilla, Opera, etc.
            parser=new DOMParser();
            xmlDoc=parser.parseFromString(xmlString,"text/xml");
        }
        catch(e){
            alert(e.message);
            return;
        }
    }
    return xmlDoc;
}

/**
 * Standard ajax get HTTP request object function
 * returns the http request object
 */
function GetHttpObject(){

    var httpRequest=null;
    try{
        // Firefox, Opera 8.0+, Safari
        httpRequest=new XMLHttpRequest();
    } catch (e) {
        //Internet Explorer
        try{
            httpRequest=new ActiveXObject("Msxml2.XMLHTTP");
        }catch (e){
            httpRequest=new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    return httpRequest;
}
