<?xml version="1.0" encoding="UTF-8" ?> 
<Module>
  <ModulePrefs  
    title="MyVox Voice Blog Admin"
    directory_title="MyVox Voice Blog Admin"
    description="The MyVox Voice Blog Admin gadget allows you to create a voice blog and record and manage voice posts. The voice recording is performed over the phone, so there is no need for a microphone and complicated software. Once your Voice Blog has been created, send a link to the listener gadget for your blog to your friends by email, post the link on your website, or even add a live listener gadget on your website or your blog, where your visitors will be able to listen to your latest voice posts. This service is powered by MyVox API from VoodooVox."
    screenshot="http://api.myvox.com/demo/igoogle/voiceblog_screenshot.png"
    thumbnail="http://api.myvox.com/demo/igoogle/voiceblog_thumbnail.png"
    author="Jerome Mouton"
    author_email="igoogle_gadgets@ljmsite.com"
    author_location="Huntsville, AL, USA"
    author_affiliation="LjmSite"
    author_aboutme="Google API gadget and web application developer, tech project manager in globally dispersed team environment, computer geek on call, etc. Come check me out at LjmSite.com and contact me to discuss gadget projects or opportunities."
    author_link="http://www.ljmsite.com/"
    author_photo="http://www.ljmsite.com/google/gadgets/jerome.png"
    singleton="false"
    height="300">
    <Require feature="analytics"/>
    <Require feature="dynamic-height"/>
    <Require feature="setprefs"/>
    <Require feature="flash"/>
    <Require feature="settitle"/>
  </ModulePrefs>
  <UserPref name="recording_list_key" display_name="Blog key"/>
  <UserPref name="password" display_name="Blog password"/>
  <UserPref name="nbentries" display_name="Number of entries" datatype="enum" default_value="5">
    <EnumValue value="1"/>
    <EnumValue value="2"/>
    <EnumValue value="3"/>
    <EnumValue value="4"/>
    <EnumValue value="5"/>
    <EnumValue value="6"/>
    <EnumValue value="7"/>
    <EnumValue value="8"/>
    <EnumValue value="9"/>
  </UserPref>
  <UserPref name="recsession" datatype="hidden" default_value="---"/>
  <UserPref name="recphone" datatype="hidden" default_value="---"/>
  <UserPref name="recpin" datatype="hidden" default_value="---"/>
  <Content type="html">  
<![CDATA[

<style type="text/css">
* {
    font-family:Arial,Helvetica,sans-serif;
    font-weight:bold;
    text-align:left;
    vertical-align:middle;
    font-size:13;
    color:#000000;
    background-color:#ffffff;
}
.title, a.title:link, a.title:visited {
    color:#1772a5;
    text-decoration:none;
}
.date {
    color:#514246;
    font-size:10;
    text-decoration:none;
}
.recorder {
    text-align:center;
    padding:3px;
}
.footer {
    text-align:center;
    font-weight:normal;
    text-align:left;
    vertical-align:middle;
    font-size:11;
    color:#111111;
}
.status {
    font-weight:normal;
}
img {
    border:0px;
}
td.icon {
    vertical-align:middle;
}
</style>

<div id="recorder" class="recorder"></div>
<div id="content"></div>
<div id="footer" class="footer"></div>

<script type="text/javascript">

// Author  : Jerome Mouton - LjmSite
// Customer: MyVox
// Version : 1.2, 3/02/2008
// Icon design credits:  
//   - most icons from http://www.famfamfam.com/lab/icons/silk/
//   - wait.gif icon from http://www.sanbaldo.com/wordpress/1/ajax_gif/
// Flash mp3 player credit:
//   - http://musicplayer.sourceforge.net/
//     Copyright (c) 2005, Fabricio Zuardi, All rights reserved.
///////////////////////////////////////////////////////////////////////////

// URL of the location where the gadget supporting content is available
///////////////////////////////////////////////////////////////////////////
var rootUrl = 'http://api.myvox.com/demo/igoogle/';

// Special password which switches the gadget in listener mode
///////////////////////////////////////////////////////////////////////////
var listenerPassword = 'myVoxLjmSite';

// Globals
///////////////////////////////////////////////////////////////////////////
var prefs;           // iGoogle prefs management object
var iconDelete;      // URLs to the application icons
var iconEdit;  
var iconPlay;    
var iconRec;
var iconTelephoneng;
var iconLock;
var iconCancel;
var iconAccept;
var iconDims = 'width="16" height="16"';

_IG_RegisterOnloadHandler(init);

///////////////////////////////////////////////////////////////////////////
// Initialization function
///////////////////////////////////////////////////////////////////////////
function init() {
    // iGoogle prefs management object
    prefs = new _IG_Prefs(__MODULE_ID__);

    myVox.initAPI('68BVJZZTJD', prefs.getString('recording_list_key'), prefs.getString('password'));

    // Icon URLs cached on Google systems for fastest load
    iconDelete    = _IG_GetImageUrl(rootUrl + 'delete.png');
    iconEdit      = _IG_GetImageUrl(rootUrl + 'edit.png');
    iconPlay      = _IG_GetImageUrl(rootUrl + 'play.png');
    iconRec       = _IG_GetImageUrl(rootUrl + 'record.png');
    iconTelephone = _IG_GetImageUrl(rootUrl + 'telephone.png');
    iconLock      = _IG_GetImageUrl(rootUrl + 'lock.png');
    iconCancel    = _IG_GetImageUrl(rootUrl + 'cancel.png');
    iconAccept    = _IG_GetImageUrl(rootUrl + 'accept.png');
    iconWait      = _IG_GetImageUrl(rootUrl + 'wait.gif');
    iconMyVox     = _IG_GetImageUrl(rootUrl + 'powered_by_myvox.png');

    _gel('content').innerHTML = '<img src="' + iconWait + '" alt="wait for refresh" /> <i>Please wait...</i>'

    updateRecordingStatus();
    getPosts();
    setFooter();

    _IG_Analytics("UA-1189083-1", "/voiceblog/1");
}

///////////////////////////////////////////////////////////////////////////
// Creation of a new Voice Blog
///////////////////////////////////////////////////////////////////////////
function getHtmlNewBlog() {
    var htmlArray = [
        '<tr><td class="title">Welcome to the MyVox Voice Blog iGoogle gadget. Set a title and a password to get started:',
        '<form class="title" onsubmit="createNewVoiceBlog(this); return false;">',
        '<table><tr><td>Title:</td><td><input type="text" id="name" name="name" value="" size="20" /></td></tr>',
        '<tr><td>Password:</td><td><input type="text" id="passwd" name="passwd" value="" size="10" />',
        '&nbsp;<input type="submit" value="save" /></td></tr></table></form>',
        '<td></tr>'
    ];
    
    return htmlArray.join('');
}

function createNewVoiceBlog(form) {
    var name = form.name.value;
    var passwd = form.passwd.value;

    if(name == '') {
        alert('Voice Blog title can not be blank.');
        return;
    }
    if(name.length > 50) {
        alert('Voice Blog title can not longer than 50 chars.');
        return;
    }
    
    if(passwd.length < 6) {
        alert('Voice Blog password must be at least 6 chars long.');
        return;
    }
    prefs.set('password', passwd);
    
    // Create the new voice blog on the MyVox server
    myVox.createRecordingList(name, passwd, createNewVoiceBlogCallback);
}

function createNewVoiceBlogCallback(response) {
    var recording_list_key = myVox.getValueByTagName(response, 'recording_list_key');
    if(recording_list_key) {
        prefs.set('recording_list_key', recording_list_key);

        myVox.initAPI('68BVJZZTJD', recording_list_key, prefs.getString('password'));
        _gel('content').innerHTML = '<img src="' + iconWait + '" alt="wait for refresh" /> <i>Please wait...</i>'
        updateRecordingStatus();
        getPosts();
        setFooter();
    }
    else {
        alert('An error occured while creating the new Voice Blog. Please try again later.');
    }
}

///////////////////////////////////////////////////////////////////////////
// Management of the status of the recording
///////////////////////////////////////////////////////////////////////////
function updateRecordingStatus() {
    if(isListenerMode()) {
        // Listener mode of gadget does not display any recording utility
        return;
    }

    if(isNotSetup()) {
        // The gadget is in Blog Management mode but has not yet been setup
        return;
    }

    // recording_key user prefs keeps track if a recording is in progress
    var recording = prefs.getString("recording_key");

    var recsession = prefs.getString('recsession');
    var recphone = prefs.getString('recphone');
    var recpin = prefs.getString('recpin');

    // No recording in progress, display the new recording button
    if((recsession == '---') || (recphone == '---') || (recpin == '---')){
        var htmlArray = [
            '<a href="javascript:void(0);" onclick="javascript:recordingStart();">',
            '<img src="', iconRec, '" alt="Record New Post" /></a>'
        ];

        _gel("recorder").innerHTML = htmlArray.join('');
    }
    // A recording is in progress, display the call information/status
    else {
        displayStatus(recphone, recpin);
        myVox.getSessionStatus(recsession, recordingShowStatus);
    }
}

function displayStatus(phone_number, ivr_pin) {
    var messageHtml = 'To record your new post, call<br /><img src="' + iconTelephone
                      + '" alt="phone number" />&nbsp;' + phone_number
                      + '&nbsp;&nbsp;<img src="' + iconLock + '" alt="pin" />&nbsp;'
                      + ivr_pin
                      + '<br />Status: <span class="status" id="recstatus">Waiting for call...</span>'
                      + '&nbsp;<a href="javascript:void(0);" onclick="javascript:endRecordingPrompt();">'
                      + '<img src="' + iconCancel + '" alt="cancel recording" /></a><br />';

    _gel("recorder").innerHTML = messageHtml;
        
    _IG_AdjustIFrameHeight();
}

///////////////////////////////////////////////////////////////////////////
// New Voice Blog post recording
///////////////////////////////////////////////////////////////////////////
function recordingStart() {
    myVox.createRecording('new recording', recordingCreate);
}

function recordingCreate(response) {
    var recording_key = myVox.getValueByTagName(response, 'recording_key');
    if(recording_key) {
        myVox.startRecordingSession(recording_key, recordingDisplayPhoneNumber);
    }
    else {
        errorCommand();
    }
}

function recordingDisplayPhoneNumber(response) {
    var phone_number = myVox.getValueByTagName(response, 'phone_number');
    var ivr_pin = myVox.getValueByTagName(response, 'ivr_pin');
    var recording_session_key = myVox.getValueByTagName(response, 'recording_session_key');
    if(phone_number && ivr_pin && recording_session_key) {
        // format phone number
        phone_number = formatPhoneNumber(phone_number);

        // Now that the session is ready, save the parameters in iGoogle user prefs
        // such as we can continue from where we were after a page refresh
        prefs.set('recsession', recording_session_key);
        prefs.set('recphone', phone_number);
        prefs.set('recpin', ivr_pin);

        displayStatus(phone_number, ivr_pin);
        
        myVox.getSessionStatus(recording_session_key, recordingShowStatus);
    }
}

function recordingShowStatus(response) {
    var recstatus = _gel("recstatus");
    if(recstatus) {
        var state = myVox.getValueByTagName(response, 'recording_state');
        var recsession = prefs.getString('recsession');
        
        if(state == 'unrecorded') {
            recstatus.innerHTML = 'Waiting for call...';
            setTimeout('myVox.getSessionStatus(\'' + recsession + '\',recordingShowStatus)', 3000);
        }
        else if(state == 'recording') {
            recstatus.innerHTML = 'Call in progress';
            setTimeout('myVox.getSessionStatus(\'' + recsession + '\',recordingShowStatus)', 3000);
        }
        else if(state == 'recorded') {
            recstatus.innerHTML = 'Recording completed.';
            setTimeout('endRecording()', 3000);
        }
        else {
            endRecording();
        }       
    } else {
        endRecording();
    }
}

function endRecordingPrompt() {
    var answer = confirm('Are you sure you want to cancel the recording?');
    if(answer){
        endRecording();
    }
}

function endRecording() {
    prefs.set('recsession', '---');
    prefs.set('recphone', '---');
    prefs.set('recpin', '---');
    
    // Clear the recording status and put back the record button
    updateRecordingStatus();
    
    // Refresh the list of recording
    getPosts();
}

///////////////////////////////////////////////////////////////////////////
// Actions on existing posts
///////////////////////////////////////////////////////////////////////////
function deletePost(id) {
    var name = _gel('title' + id).innerHTML;
    var answer = confirm('Are you sure you want to delete the Post "' + name + '"?');
    if (answer){
        myVox.deleteRecording(id, function(response) {
            // Can not infer result on voice_recorder_key on a delete command
            //if(myVox.getValueByTagName(response, 'voice_recorder_key') == '') {
            //    errorCommand();
            //}

            // Refresh the list of posts
            getPosts();
        });
    }
}

function editPost(id) {
    var name = _gel('title' + id).innerHTML;
    // Replace the title, date and icon with a text field for title editing
    var htmlArray = [
        '<form class="title" onsubmit="editTitleAction(this); return false;">',
        '<input type="hidden" id="key" name="key" value="' + id + '" />',
        '<input type="text" id="name" name="name" value="',
        name, '" size="30" />',
        '&nbsp;<input type="image" src="', iconAccept, '" value="save" />',
        '&nbsp;<a href="javascript:void(0);" onclick="javascript:updateRecordingStatus();">',
        '<img src="' + iconCancel + '" alt="cancel edit" /></a></form>'
    ];
    
    _gel('recorder').innerHTML = htmlArray.join('');
}

function editTitleAction(form) {
    var id = form.key.value;
    var name = form.name.value;
    if(name.length > 50) {
        alert('New title too long - maximum 50 chars allowed.');
        return;
    }
    if(name.indexOf('"') != -1) {
        alert('No " (double quote) allowed in the title.');
        return;
    }
    _gel(id).innerHTML = '<img src="' + iconWait + '" alt="wait for refresh" />';
    myVox.setRecording(id, name, function(response) {
        if(myVox.getValueByTagName(response, 'voice_recorder_key') == '') {
            errorCommand();
        }

        // Clear the text area and refresh the list of posts
        updateRecordingStatus();
        getPosts();
    });
}

// Not used anymore - because of a bug in the Flash MP3 player (when starting with autoplay
// the player can not always be stopped), we changed the process and start the player on
// every visible post on load (instead of just showing a bitmap with an onclick).
function playPost(id, mp3_url) {
    _IG_EmbedFlash(
        rootUrl + 'musicplayer.swf?song_url=' + mp3_url + '&autoplay=true',
        id, {wmode: "window", width: 17, height: 17});
        // Could not get the Google API caching to work for this Flash app
        // _IG_GetCachedUrl(rootUrl + 'musicplayer.swf'),
        // id, {wmode: "window", width: 17, height: 17, autoplay: "true", song_url: mp3_url});
}


///////////////////////////////////////////////////////////////////////////
// Display the Voice Blog latest posts
///////////////////////////////////////////////////////////////////////////
function getPosts() {
     myVox.getRecording(displayPosts);
}

function displayPosts(response) {
    var storiesHtml = '<table border="0">';
    var blogPosts = [];

    // Get a list of the <recording> element nodes in the response
    var recordings = response.getElementsByTagName("recording");
    
    if(recordings && recordings.length > 0) {
        // Loop through all <recording> nodes
        for(var i = 0; i < recordings.length; i++) { 
            var name = '';
            var mp3_url = '';
            var date_created = '';
            var recording_key = '';
            var length = 0;

            // Get child nodes for the current <recording> note
            var nodeList = recordings.item(i).childNodes;

            // Loop through child nodes. Extract data from the text nodes that are
            // the children of the associated name, mp3_url, date_created and recording_key
            // element nodes.
            for (var j = 0; j < nodeList.length ; j++) {
                var node = nodeList.item(j);
                
                if(node.nodeName == 'name') {
                    name = node.firstChild.nodeValue.replace(/"/g, '&quot;');
                }
                else if(node.nodeName == 'mp3_url') {
                    mp3_url = node.firstChild.nodeValue;
                }
                else if(node.nodeName == 'date_created') {
                    date_created = node.firstChild.nodeValue;
                }
                else if(node.nodeName == 'recording_key') {
                    recording_key = node.firstChild.nodeValue;
                }
                else if(node.nodeName == 'recording_length') {
                    length = node.firstChild.nodeValue;
                }
            }
            if(mp3_url && recording_key) {
                blogPosts.push(formatOnePost(name, mp3_url, date_created, recording_key, length));
            }
        }
        
        if(blogPosts.length > 0) {
            var postCounter = __UP_nbentries__;
            while(blogPosts.length && postCounter) { 
                storiesHtml += blogPosts.pop();
                postCounter--;
            }
        }
        else {
            storiesHtml += '<tr><td>No blog post recorded yet.</td></tr>';
        }
    }
    else {
        var key = response.getElementsByTagName("recording_list_key");
        if(key && key.length) {
            storiesHtml += '<tr><td>No blog post recorded yet.</td></tr>';
        }
        else if(prefs.getString('recording_list_key')) {
            storiesHtml += '<tr><td>Invalid blog key: ' + prefs.getString('recording_list_key') + '<br /><br />Please put the correct blog key in the gadget settings.</td></tr>';
            _gel("recorder").innerHTML = '';
        }
        else if(isNotSetup()) {
            storiesHtml += getHtmlNewBlog();
            _gel("recorder").innerHTML = '';
        }
        else {
            storiesHtml += '<tr><td>Please put the correct blog key in the gadget settings.</td></tr>';
            _gel("recorder").innerHTML = '';
        }
    }

    storiesHtml += '</table>';
    _gel("content").innerHTML = storiesHtml;
    _IG_AdjustIFrameHeight();
    // Perform another adjust 3 seconds later
    setTimeout('_IG_AdjustIFrameHeight()',3000);

    // Set the Gadget title with the Voice Blog Title
    if(prefs.getString('recording_list_key') != '') {
        myVox.getRecordingList(setBlogTitle);
    }
    
    return;
}

function formatOnePost(name, mp3_url, date_created, recording_key, length) {
    var playerHtml = '<object type="application/x-shockwave-flash" width="17" height="17" '
                   + 'data="' + rootUrl + 'musicplayer.swf?song_url=' + mp3_url
                   + '"><param name="movie" value="' + rootUrl + 'musicplayer.swf?song_url='
                    + mp3_url + '" /></object>';


    // Listener mode with minimal interface
    if(isListenerMode()) {
        var htmlArray = [
            '<tr><td class="title">', name,
            '<br /><span class="date">', date_created, ' - ', formatDuration(length), '</span></td>', 
            '<td class="icon">', playerHtml, '</td></tr>'];
            
        return htmlArray.join('');
    }
    
    // Admin mode with full interface to delete and edit
    var htmlArray = [
        '<tr><span id="edit', recording_key, '">',
        '<td class="icon"><a href="javascript:void(0);" onclick="javascript:deletePost(\'',
        recording_key, '\');"><img src="', iconDelete,
        '" alt="delete this post" /></a></td><td><span id="title', recording_key, '" class="title">',
        name, '</span><br /><span class="date">', date_created, ' - ',
        formatDuration(length), '</span></td>', 
        '<td class="icon" width="35"><span id="', recording_key,
        '"><a href="javascript:void(0);" onclick="javascript:editPost(\'',
        recording_key, '\');"><img src="', iconEdit,
        '" alt="edit title" /></span>', '</a>', playerHtml, '</td></span></tr>'];
    
    return htmlArray.join('');
}

function setBlogTitle(response) {
    var title = myVox.getValueByTagName(response, 'name');
    if(title) {
        _IG_SetTitle(title);
    }
}


///////////////////////////////////////////////////////////////////////////
// Generator for the footer based on the use type
///////////////////////////////////////////////////////////////////////////
function setFooter() {
    var html = '';
    if(isListenerMode() || isNotSetup()) {
         if(window.location.toString().indexOf('synd=open') == -1) {
             html = '<div style="text-align:center"><a href="http://www.myvox.com/"><img src="' + iconMyVox
                    + '" alt="powered by MyVox" /></a></div>';
         }
         else {
         html = '<hr /><table><tr><td><a href="http://www.myvox.com/" target="_blank"><img src="'
                + iconMyVox + '" alt="powered by MyVox" /></a></td><td class="footer">'
                + '<a class="footer" href="http://www.google.com/ig/adde?up_recording_list_key='
                + prefs.getString('recording_list_key') + '&moduleurl=' + rootUrl + 'listener.xml'
                + '" target="_blank">Subscribe to this Voice Blog on my iGoogle</a>'
                + '</td></tr></table>';
         }
    }
    else {
         html = '<hr /><table><tr><td><a href="http://www.myvox.com/" target="_blank"><img src="'
                + iconMyVox + '" alt="powered by MyVox" /></a></td><td class="footer">'
                + 'Blog key: ' + prefs.getString('recording_list_key')
                + '<br />Listener gadget: <a class="footer" href="http://www.google.com/ig/adde?up_recording_list_key='
                + prefs.getString('recording_list_key') + '&moduleurl=' + rootUrl + 'listener.xml'
                + '" target="_blank">link</a>'
                + '<br /><a class="footer" href="http://gmodules.com/ig/creator?synd=open&up_recording_list_key='
                + prefs.getString('recording_list_key') + '&url=' + rootUrl + 'listener.xml'
                + '" target="_blank">Add to your website</a>'
                + '</td></tr></table>';
    }
    _gel('footer').innerHTML = html;
}

///////////////////////////////////////////////////////////////////////////
// Generic message when a password protected command fails
///////////////////////////////////////////////////////////////////////////
function errorCommand() {
    alert('Error while executing your command - please ensure your Voice Blog password is correct.');
}

///////////////////////////////////////////////////////////////////////////
// Check if the gadget is in Listener mode (listener.xml)
///////////////////////////////////////////////////////////////////////////
function isListenerMode() {
    return (prefs.getString('password') == listenerPassword);
}

///////////////////////////////////////////////////////////////////////////
// Check if the gadget has been setup with a blog id
///////////////////////////////////////////////////////////////////////////
function isNotSetup() {
    return (prefs.getString('recording_list_key').length == 0);
}

///////////////////////////////////////////////////////////////////////////
// Substring utility with pre and post string delimiters
///////////////////////////////////////////////////////////////////////////
function getSubstring(data, pre, post) {
    var val = '';
    var start = data.indexOf(pre);
    if(start != -1) {
        start += pre.length;
        var data2 = data.substring(start);
        var end = data2.indexOf(post);
        if(end != -1) {
            val = data2.substring(0, end);
        }
    }
    return val;
}

///////////////////////////////////////////////////////////////////////////
// Gadget iframe width utility
///////////////////////////////////////////////////////////////////////////
function getGadgetWidth() {
    var w;
    if(self.innerHeight) {
        w = self.innerWidth;
    }
    else if(document.documentElement && document.documentElement.clientHeight) {
        w = document.documentElement.clientWidth;
    }
    else if(document.body) {
        w = document.body.clientWidth;
    }
    return w;
}

///////////////////////////////////////////////////////////////////////////
// Raw phone number formater utility
///////////////////////////////////////////////////////////////////////////
function formatPhoneNumber(phone) {
  if(phone.length == 10) {
      // Format as a US phone number
      var areacode = phone.substring(0,3);
      var exchcode = phone.substring(3,6);
      var lastdigi = phone.substring(6,10);
      return '(' + areacode + ') ' + exchcode + '-' + lastdigi;
  }
  return phone;
}

///////////////////////////////////////////////////////////////////////////
// Duration formater utility (seconds to min:sec)
///////////////////////////////////////////////////////////////////////////
function formatDuration(seconds) {
    var secs = seconds % 60;
    var mins = Math.floor(seconds / 60);
    var duration = '';
    if(mins < 10) {
        duration = '0' + mins + ':';
    }
    else {
        duration = mins + ':';
    }

    if(secs < 10) {
        duration += '0' + secs;
    }
    else {
        duration += secs;
    }
    
    return duration;
}

//////////////////////////////////////////////////////////////////////////
// MyVox Google Gadget API by LjmSite
//
// Note: This API does not expose all the capabilities of the MyVox API
//       but only focuses on the needs of the Voice Blog application.
//       Several commands are not implemented, and the commands which are
//       implemented do not expose features like caller id, metadata, etc.
//////////////////////////////////////////////////////////////////////////

var myVox = function() { // Creating a myVox namespace
    // Private members
    var m_recoder_key;
    var m_recording_list_key;
    var m_password;
  
    function p_fetchXml(url, callback) {
        // Add a random parameter at the end of the URL to ensure that Google
        // does not give us some cached content
        url +=  '&random=' + Math.random();
        _IG_FetchXmlContent(url, function(response) {
            if((response == null) || (typeof(response) != "object") || (response.firstChild == null)) {
                // Nothing we can do from this point...
            }
            else {
                callback(response);
            }
            return;
        }, {refreshInterval: 0});
    };
  
	  return {
	  //////////////////////////////////////////////////////////////////////
	  //////////////////////////////////////////////////////////////////////
	  // F U N C T I O N S    T O    I N I T I A T E    C O M M A N D S
	  //////////////////////////////////////////////////////////////////////
	  //////////////////////////////////////////////////////////////////////
	  
    //////////////////////////////////////////////////////////////////////
    // Initialize the parameters required for the API
    //////////////////////////////////////////////////////////////////////
    initAPI : function(recorder_key, recording_list_key, password) {
        m_recorder_key = recorder_key;
        m_recording_list_key = recording_list_key;
        m_password = password;
    },

    //////////////////////////////////////////////////////////////////////
    // Adds a new recording placeholder to a RecordingList instance and
    // updates the sequence	numbers of any others to keep them consecutive
    // Important fields available in response: recording_key
    //////////////////////////////////////////////////////////////////////
    createRecording : function(name, callback) {
        p_fetchXml('http://api.myvox.com/vr?action=CreateRecording' +
                   '&voice_recorder_key=' + _esc(m_recorder_key) +
                   '&recording_list_key=' + _esc(m_recording_list_key) +
                   '&password=' + _esc(m_password) +
                   '&name=' + _esc(name), callback);
    },
    
    //////////////////////////////////////////////////////////////////////
    // Creates a new RecordingList containing one or more recording
    // placeholders within a VoiceRecorder application instance.
    //////////////////////////////////////////////////////////////////////
    createRecordingList : function(name, password, callback) {
        p_fetchXml('http://api.myvox.com/vr?action=CreateRecordingList' +
                   '&voice_recorder_key=' + _esc(m_recorder_key) +
                   '&update_password=' + _esc(password) +
                   '&delete_password=' + _esc(password) +
                   '&name=' + _esc(name), callback);
    },

    //////////////////////////////////////////////////////////////////////
    // Deletes a single recording from a RecordingList instance and updates
    // the sequence numbers of any others to keep them consecutive.
    //////////////////////////////////////////////////////////////////////
    deleteRecording : function(recording_key, callback) {
        p_fetchXml('http://api.myvox.com/vr?action=DeleteRecording' +
                   '&voice_recorder_key=' + _esc(m_recorder_key) +
                   '&recording_list_key=' + _esc(m_recording_list_key) + 
                   '&password=' + _esc(m_password) +
                   '&recording_key=' + _esc(recording_key), callback);
    },
    
    //////////////////////////////////////////////////////////////////////
    // Deletes a RecordingList instance and all recordings associated
    // with it
    //////////////////////////////////////////////////////////////////////
    deleteRecordingList : function(callback) {
        // NOT IMPLEMENTED
        callback(null);
    },
    
    //////////////////////////////////////////////////////////////////////
    // Expire a recording session and unlock all recordings bound to the
    // current session
    //////////////////////////////////////////////////////////////////////
    expireRecordingSession : function(callback) {
        // NOT IMPLEMENTED
        callback(null);
    },
    
    //////////////////////////////////////////////////////////////////////
    // Returns data for a Recording instance associated with a
    // RecordingList instance
    //////////////////////////////////////////////////////////////////////
    getRecording : function(callback) {
        p_fetchXml('http://api.myvox.com/vr?action=GetRecording' +
                   '&voice_recorder_key=' + _esc(m_recorder_key) +
                   '&recording_list_key=' + _esc(m_recording_list_key), callback);
    },
    
    //////////////////////////////////////////////////////////////////////
    // Returns data for a RecordingList instance within the VoiceRecorder
    // application instance
    //////////////////////////////////////////////////////////////////////
    getRecordingList : function(callback) {
        p_fetchXml('http://api.myvox.com/vr?action=GetRecordingList' +
                   '&voice_recorder_key=' + _esc(m_recorder_key) +
                   '&recording_list_key=' + _esc(m_recording_list_key), callback);
    },
    
    //////////////////////////////////////////////////////////////////////
    // Returns the status of the current recording session.
    //////////////////////////////////////////////////////////////////////
    getSessionStatus : function(recording_session_key, callback) {
        p_fetchXml('http://api.myvox.com/vr?action=GetSessionStatus' +
                   '&recording_session_key=' + _esc(recording_session_key), callback);
    },
    
    //////////////////////////////////////////////////////////////////////
    // Updates the values of a Recording instance
    //////////////////////////////////////////////////////////////////////
    setRecording : function(recording_key, name, callback) {
        p_fetchXml('http://api.myvox.com/vr?action=SetRecording' +
                   '&voice_recorder_key=' + _esc(m_recorder_key) +
                   '&recording_list_key=' + _esc(m_recording_list_key) +
                   '&password=' + _esc(m_password) +
                   '&recording_key=' + _esc(recording_key) +
                   '&name=' + _esc(name), callback);
    },
    
    //////////////////////////////////////////////////////////////////////
    // Updates the values of a RecordingList instance
    //////////////////////////////////////////////////////////////////////
    setRecordingList : function(callback) {
        // NOT IMPLEMENTED
        callback(null);
    },
    
    //////////////////////////////////////////////////////////////////////
    // Initiate a recording session to voice the recordings in a
    // RecordingList over the phone.
    // Important fields available in response: phone_number, ivr_pin
    //////////////////////////////////////////////////////////////////////
    startRecordingSession : function(recording_key, callback) {
        p_fetchXml('http://api.myvox.com/vr?action=StartRecordingSession' +
                   '&voice_recorder_key=' + _esc(m_recorder_key) +
                   '&recording_list_key=' + _esc(m_recording_list_key) +
                   '&password=' + _esc(m_password) +
                   '&recording_keys=' + _esc(recording_key), callback);
    },
    

	  //////////////////////////////////////////////////////////////////////
	  //////////////////////////////////////////////////////////////////////
	  // R E S P O N S E    P A R S E R    U T I L I T I E S
	  //////////////////////////////////////////////////////////////////////
	  //////////////////////////////////////////////////////////////////////
   
    //////////////////////////////////////////////////////////////////////
    // Get the value of a unique node
    //////////////////////////////////////////////////////////////////////
    getValueByTagName : function(response, tagName) {
        if(response && 
           response.getElementsByTagName(tagName) &&
           response.getElementsByTagName(tagName).item(0) &&
           response.getElementsByTagName(tagName).item(0).firstChild) {
            return response.getElementsByTagName(tagName).item(0).firstChild.nodeValue;
        }
        return '';
    }    
		
	};
}();

</script>

]]> 
  </Content>
</Module>
