/**
* @classDescription Interface object to encapsulate API 
* commands between javascript and inteleview
*
* @constructor
* @param input_placeholder - string ID of the placeholder element on the page.
* @param input_settings - settings for the IVJ instance
*/
function ivj(input_placeholder, input_settings)
{
    //Properties: Page Elements
    this.object = null;
    this.placeholder = null;

    //Properties: Positioning
    this.offset = null;
    this.width = 0;
    this.height = 0;
    this.scroll_y = 0;

    //Properties: Animation
    this.script = null;

    //Properties: State
    this.settings = null;
    this.id = null;
    this.full_screen = false;
    this.loaded = false;

    try
    {
        ivj.log("performing checks");

        //Validate: Make sure we have jquery.
        if($==undefined || (/1\.(0|1|2)\.(0|1|2)/).test($.fn.jquery))
            throw ivj.strings.en['error_no_jquery'];

        //Validate: Make sure we have plugin detect script
        if(PluginDetect==undefined)
            throw ivj.strings.en['error_no_plugindetect'];

        //Validate: Make sure we have placeholder element
        this.placeholder = $('#'+input_placeholder);
        if(!this.placeholder.length)
            throw ivj.strings.en['error_no_placeholder'];

        //Setup: Get all settings.
        this.settings = $.extend({
            'width':null,
            'height':null,
            'id':null,
            'allow_full_screen': true,
            'auth_token':null,
            'group_id':null,
            'startup_action':'none',
            'startup_location':null,
            'startup_script':null,
            'show_side_panel':true,
            'on_startup_callback':null,
            'on_fullscreen_start_callback':null,
            'on_fullscreen_end_callback':null,
            'on_exit_callback':null,
            'path':'',
            'ivj_path':'',
            'click_to_start':false,
            'lang':'en'
        },input_settings);

        //Setup: get ID
        this.id = this.settings.id == undefined ?
            ivj.generate_id() : this.settings.id;

        //add to static instances so we can reference it later
        ivj.instances[this.id] = this;

        //Setup: Get positioning info
        this.offset = this.placeholder.offset();
        this.width = this.settings.width == undefined ?
            this.placeholder.width() : this.settings.width;
        this.height = this.settings.height == undefined ?
            this.placeholder.height() : this.settings.height;

        //add startup script
        if(this.settings.startup_script)
            this.script = this.settings.startup_script;

        //add to page
        this.add();
    }
    catch(err)
    {
        alert(err);
    }
}

//static properties
ivj.overlays = [];
ivj.instances = {};
ivj.debug = false;
ivj.strings = {
    'en':{
        'tip':"InteleView is a powerful online GIS tool for displaying vast quantities of data, in real time, from around the world, and displaying it in a way that is intuitive and easy to use.",
        'old_java': "The version of Java installed on your machine is not the latest and could cause InteleView to run slowly.",
        'no_java': "Java was not detected on your machine, or your version of java is too old to run InteleView. It may be disabled, or it may not be installed.",
        'mac_old': "The version of Java installed on your machine is the latest for your platform, however, it limits the capabilities of InteleView and may cause it to run slowly",
        'click_to_load': "InteleView will run successfully on your system!",
        'mac_firefox': "InteleView will run successfully on your system, however, additional features may be available using Safari.",
        'popup_title':'InteleView',
        'error_detecting_java':'There was a problem detecting the java capabilities of your browser.',
        'error_adding_inteleview':'There was a problem adding InteleView to the page.',
        'error_no_placeholder':'Placeholder element was not found.',
        'error_no_plugindetect':'Plugin Detection library was not found.',
        'error_no_jquery':'jQuery library was not found.',
        'error':'Error',
        'details':'Details',
        'options':'InteleView Options',
        'option_continue':'Continue with the current version of Java',
        'option_download':'Download the latest version  of Java here.',
        'option_webstart':'Use InteleView WebStart',
        'new_window':'Opens in a new window.',
        'loading':'InteleView is Loading'
    },
    'es':{
        'tip': 'El visualizador GEO-MEXICO, de la Presidencia de la República está cargando en su equipo de cómputo, esto puede durar algunos minutos. ',
        'old_java': 'La versión de Java instalada en su máquina no es el más reciente y podría causar InteleView a funcionar lentamente.',
        'no_java': 'Java no se ha detectado en su máquina, o su versión de Java es demasiado viejo para correr InteleView. Puede ser desactivado, o no puede ser instalado.',
        'mac_old': 'La versión de Java instalada en su máquina es la más reciente para su plataforma, sin embargo, limita la capacidad de InteleView y puede provocar que se ejecute lentamente',
        'click_to_load': 'InteleView se ejecutará correctamente en su sistema!',
        'mac_firefox': 'InteleView se ejecutará correctamente en su sistema, sin embargo, las características adicionales pueden ser accesibles por medio de Safari.',
        'popup_title': 'InteleView',
        'error_detecting_java': 'Ha habido un problema la detección de las capacidades de Java de su navegador.',
        'error_adding_inteleview': 'Hubo un problema al añadir InteleView a la página.',
        'error': 'Error',
        'details': 'Detalles',
        'options': 'Opciones de InteleView',
        'option_continue': 'Continuar con la versión actual de Java',
        'option_download': 'Descarga la última versión de Java aquí.',
        'option_webstart': 'Usar InteleView WebStart',
        'new_window': 'Se abre en una ventana nueva.',
        'loading': 'InteleView está cargando'
    }
};

/**
 *Generate a random ID
 *
 *@method
 *@static
 *@returns string
 */
ivj.generate_id = function()
{
    var chars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
    var string_length = 12;
    var randomstring = '';
    for (var i=0; i<string_length; i++)
    {
        var rnum = Math.floor(Math.random() * chars.length);
        randomstring += chars.substring(rnum,rnum+1);
    }
    return randomstring;
}

/**
 *Get the platform name
 *
 *@method
 *@static
 *@returns string
 */
ivj.platform = function()
{
    if(/Win/.test(navigator.platform)) return "Win";
    else if(/Mac/.test(navigator.platform)) return "Mac";
    else if(/Linux/.test(navigator.platform)) return "Linux";
    else return "Unknown";
}

/**
 * Log debugigng info to firebug or safari console or the page
 *
 *@static
 *@method
 *@returns void
 */
ivj.log = function(message)
{
    if(ivj.debug)
    {
        if(typeof(window["console"]) != "undefined") console.log(message);
        else $('body').append("<p>"+message+"</p>");
    }
}

/**
 * Localize a string.
 *
 * @method
 * @param <string>
 * @return <string>
 */
ivj.prototype.localize = function(s)
{
    //ignore set language if there is no localization
    if(ivj.strings[this.settings.lang]==undefined) this.settings.lang = 'en';
    if(ivj.strings[this.settings.lang][s]==undefined)
    {
        if(this.settings.lang == 'en' || ivj.strings['en'][s]==undefined) return '';
        return ivj.strings['en'][s];
    }
    return ivj.strings[this.settings.lang][s];
}

/**
 *Do plugin version detection and branch based on environment.
 *
 *@method
 *@return void
 */
ivj.prototype.add = function()
{
    try
    {
        ivj.log("Adding applet.");

        //get the java environment details. Test for applet tag only
        info = PluginDetect.getInfo(
            'Java',
            this.settings.path + 'resources/getJavaInfo.jar',
            [0,2,0]
        );

        //second test: version we like?
        if(PluginDetect.isMinVersion('Java', '1,6,0,12'))
        {
            //the plugin is good. Simply add ivj.
            if(this.settings.click_to_start)
            {
                this.show_options(this.localize('click_to_load'),false,false,true);
            }
            else if(ivj.platform() == 'Mac' && !$.browser.safari)
            {
                this.show_options(this.localize('mac_firefox'), false, false, true);
            }
            else this.add_applet();
        }
        else if(PluginDetect.isMinVersion('Java', '1,5,0,2'))
        {
            //third test - latest for their platform?
            if(ivj.platform() == 'Mac')
            {
                if($.browser.safari)
                    this.show_options(this.localize('mac_old'),false,true,true);
                else
                    this.show_options(this.localize('mac_firefox'), false, true, true);
            }
            else
            {
                this.show_options(this.localize('old_java'),true,false,false);
            }
        }
        else
        {
            this.show_options(this.localize('no_java'),true,false,false);
        }
    }
    catch(err)
    {
        this.show_error(this.localize('error_detecting_java'), err);
    }
}

/**
* Add the java applet to the page.
* 
* Applet is positioned off the left hand side, and moved intop position when
* loaded.
*
* @method
* @return void
*/
ivj.prototype.add_applet = function()
{
    try
    {
        this.show_loading();
        var sidePanel = this.settings.show_side_panel ? 'true' : 'false';
        this.object = $(
            '<applet class="ivj_viewers" id="'+this.id+'" name="wwjApplet" ' +
            '   mayscript="true" code="org.jdesktop.applet.util.JNLPAppletLauncher" ' +
            '   style="position:absolute;' +
            '   top:'+this.offset.top+'px;' +
            '   left:-5000px;' +
            '   width:'+this.width+'px;' +
            '   height:'+this.height+'px;" ' +
            '   archive="'+this.settings.path+'resources/applet-launcher.jar, ' +
            '      http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jar, ' +
            '      http://download.java.net/media/gluegen/webstart/gluegen-rt.jar, ' +
            '      '+this.settings.path+'resources/inteleview.jar"> ' +
            '   <param name="jnlp_href" value="'+this.settings.path+'resources/inteleview-default.jnlp"> ' +
            '   <param name="authtoken" value="'+this.settings.auth_token+'"> ' +
            '   <param name="codebase_lookup" value="false"> ' +
            '   <param name="subapplet.classname" value="com.intelesense.inteleview.applet.InteleviewApplet"> ' +
            '   <param name="subapplet.displayname" value="InteleView 2.0 Web"> ' +
            '   <param name="noddraw.check" value="true"> ' +
            '   <param name="progressbar" value="true"> ' +
            '   <param name="cache_option" value="no" /> ' +
            '   <param name="separate_jvm" value="true" /> ' +
            '   <param name="showSidePanel" value="'+sidePanel+'" /> ' +
            '   <param name="jnlpNumExtensions" value="1"> ' +
            '   <param name="appletId" value="'+this.id+'"> ' +
            '   <param name="user_group" value="'+this.settings.group_id+'"> ' +
            '   <param name="navigateFunctionName" value="follow_link"> ' +
            '   <param name="jnlpExtension1" value="http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jnlp"> ' +
            '   <param name="java_arguments" value="-Xmx512m -Dsun.java2d.noddraw=true -Dsun.awt.noerasebackground=true"> ' +
            '</applet>'
            );
        $('body').append(this.object);

        //poll for events if we are on mac but not using safari
        if(ivj.platform() == 'Mac' && !$.browser.safari)
        {
            this.poll();
        }
    }
    catch(err)
    {
        this.show_error(this.localize('error_adding_inteleview'),err);
    }
}

/**
* Poll applet for availability
*
* In browsers which have problems triggering the appletInit and appletStart
* functions we need to poll the applet to determine when it ha sloaded
*
* @method
* @return void
*/
ivj.prototype.poll = function()
{
    ivj.log("poll called");
    try
    {
        if(this.instance().getOrbitView().getZoom())
        {
            ivj.log("poll successful");
            this.appletInit();
            thisObj = this;
            setTimeout(function() {
                thisObj.appletStart.call(thisObj);
            }, 1000);
        }
        else
        {
            throw "not ready yet";
        }
    }
    catch(err)
    {
        //setup next call
        ivj.log("poll failed: "+err);
        thisObj = this;
        setTimeout(function() {
            thisObj.poll.call(thisObj);
        }, 2000);
    }
}

/**
 *Add an overlay with additional information to the page
 *
 *
 *@method
 *@param (string) contents
 *@return void
 */
ivj.prototype.add_overlay = function(contents)
{
    $('body').append(
        $("<div></div>")
        .addClass('ivj_message_overlay')
        .addClass(this.id+'_overlay')
        .width(this.width)
        .height(this.height)
        .css({
            'top':this.offset.top + 'px',
            'left':this.offset.left + 'px'
        })
        .append(contents)
        );
}

/**
 *Remove all overlays associated with this applet
 *
 *@method
 *@return void
 */
ivj.prototype.remove_overlays = function()
{
    $('.'+this.id+'_overlay').remove();
}

/**
 *Show an error message in the overlay
 *
 *No error handling because this is in the error display path
 *
 * @method
 * @return void
 */
ivj.prototype.show_error = function(message,details)
{
    ivj.log(message+': '+details);
    var output = $("<div></div>").addClass('ivj_error').append(
        $("<h3>"+this.localize("error")+"</h3>")
        ).append(
        $("<p>"+message+"</p>")
        ).append(
        $("<a>"+this.localize("details")+"</a>").click(function(){
            $(this).after("<p>"+this.localize("details")+"</p>");
        })
    );
    this.add_overlay(output);
}

/**
 *Show an error message in the overlay
 *
 *No error handling because this is in the error display path
 *
 * @method
 * @param (string) message the message to display
 * @param (boolean) download show the download link
 * @param (boolean) webstart show the webstart link
 * @param (boolean) load show the continue loading link
 * @return void
 */
ivj.prototype.show_options = function(message,download,webstart,load)
{
    var output = $("<div></div>").addClass('ivj_options').append(
        $("<div class='ivj_header'>" +
            "<img class='ivj_logo' src='"+this.settings.path+"resources/inteleview-icon.png'/>" +
            "<h3>"+this.localize('options')+"</h3>" +
            "<img class='ivj_loading' src='"+this.settings.path+"bar.gif'/>" +
        "</div>")).append($("<p class='ivj_main_p'>"+message+"</p>")
    );
    if(load===true)
    {
        load_id = this.id;
        output.append($("<a href='#'>"+this.localize('option_continue')+"</a>").click(function(){
            ivj.instances[load_id].add_applet();
            return false;
        }));
    }
    if(download===true)
    {
        output.append("<p><a href='http://www.java.com/en/download/index.jsp'>"+
            this.localize('option_download')+"</a></p>");
    }
    if(webstart===true)
    {
        output.append("<p><a href='"+this.settings.path+"resources/inteleview-webstart.jnlp'>"+
            this.localize('option_webstart')+"</a> ("+this.localize('new_window')+")</p>");
    }
    this.add_overlay(output);
}

/**
 *Show a loading message
 *
 * @method
 * @return void
 */
ivj.prototype.show_loading = function()
{
    var output = $("<div></div>").addClass('ivj_options').append(
        $("<div class='ivj_header'>"+
            "<img class='ivj_logo' src='"+this.settings.path+"resources/inteleview-icon.png'/>"+
            "<h3>"+this.localize('loading')+"</h3>"+
            "<img class='ivj_loading' src='"+this.settings.path+"resources/loading.gif'/>"+
        "</div>")
    ).append(
        $("<p class='ivj_main_p ivj_loading_message'>"+this.localize('tip')+"</p>")
    );
    this.add_overlay(output);
}

/**
* Applet is initialized
*
* @method
* @return void
*/
ivj.prototype.appletInit = function()
{
    ivj.log('Method: appletInit is executing.');
    //turn on full screen interface elements if requested
    if (this.settings.allow_full_screen)
    {
        this.toggle_full_screen();
    }
};

/**
* Globe has rendered
*
* @method
* @return void
*/
ivj.prototype.appletStart = function()
{
    ivj.log('Method: appletStart');

    //move applet into position
    this.remove_overlays();
    this.object.css('left',this.offset.left);

    //start scripting
    if(this.settings.startup_action == 'script')
    {
        this.run_script();
    }
    else if(this.settings.startup_action == 'goto')
    {
        if(this.settings.startup_location)
            this.go_to(this.settings.startup_location);
    }
    else if(this.settings.startup_action == 'orbit')
    {
        this.script = ivj_script.default_scripts.orbit;
        this.run_script();
    }
};

/**
* Applet is exiting
*
* @method
* @return void
*/
ivj.prototype.appletStop = function()
{
    ivj.log('Method: appletStop');
};

/**
* Applet is signaling full screen
*
* @method
* @param {Bool} state: the desired full screen state
* @return void
*/
ivj.prototype.appletFullscreen = function()
{
    ivj.log('Method: appletFullscreen');

    //continue only if full screen mode is allowed
    if (this.settings.allow_full_screen)
    {
        if (this.full_screen)
        {
            this.full_screen = false;
            this.position();
        }
        else
        {
            $("body", "html").css({
                height: "100%",
                width: "100%"
            });
            this.full_screen = true;
            this.position();
        }
    }
};


/**
* Direct the applet to a new location
*
* @method
* @param {string} string_coordinates
* @return void
*/
ivj.prototype.go_to = function(string_coordinates)
{
    ivj.log('Method: go_to');

    //send correct method signatire depending on params going out
    var params = string_coordinates.split(';');
    if(params.length == 3)
        this.instance().gotoLatLon(
            parseFloat(params[1]),
            parseFloat(params[2])
            );
    else if(params.length == 4)
        this.instance().gotoLatLon(
            parseFloat(params[1]),
            parseFloat(params[2]),
            parseFloat(params[3]),0,0
            );
    else if(params.length == 5)
        this.instance().gotoLatLon(
            parseFloat(params[1]),
            parseFloat(params[2]),
            parseFloat(params[3]),
            parseFloat(params[4]),0
            );
    else if(params.length == 6)
        this.instance().gotoLatLon(
            parseFloat(params[1]),
            parseFloat(params[2]),
            parseFloat(params[3]),
            parseFloat(params[4]),
            parseFloat(params[5])
            );
};

/**
* Toggle the applet full screen awareness state
*
* @method
* @return void
*/
ivj.prototype.toggle_full_screen = function()
{
    ivj.log('Method: toggle_full_screen');
    this.instance().toggleFullscreenMode();
}

/**
* Creates or updates a screen overlay
*
* @method
* @return void
*/
ivj.prototype.screen_overlay = function(id,name,description,url,x,y,opacity,corner_radius)
{
    ivj.log('Method: screen_overlay');

    //check required params
    if(!name || !url) return false;

    //prepare optional params
    corner_radius = corner_radius || 0;
    opacity = opacity || 1;
    x = x || 0;
    y = y || 0;
    description = description || '';

    //switch action based on ID
    if(id==null)
    {
        id = ivj.generate_id();
        this.instance().addScreenOverlay(
            id, name, description, url, x, y, opacity, true, corner_radius);
        ivj.overlays.push(id);
    }
    else if(ivj.overlays.toString().search(id) !== false)
    {
        this.instance().refreshScreenOverlay(
            id, name, description, url, x, y, opacity, true, corner_radius);
    }

    //return ID
    return id;
}

/**
* Set the opacity of the layer with the provided ID
*
* @method
* @return boolean
*/
ivj.prototype.set_layer_opacity = function(id,opacity)
{
    ivj.log('Method: get_coordinates');

    //validate inputs
    if(!id || !opacity) return false;

    //direct traffic
    if(ivj.overlays.join(';').search(id) !== false)
    {
        return this.instance().setLayerOpacityById(id, opacity)
    }
    else
    {
        return this.instance().setLayerOpacityByDatabaseId(id, opacity)
    }
};

/**
* Set the visibility of the layer with the provided ID
*
* @method
* @return string
*/
ivj.prototype.set_layer_visibility = function(id,state)
{
    ivj.log('Method: get_coordinates');

    //validate inputs
    if(!id || !state) return false;

    //direct traffic
    if(ivj.overlays.join(';').search(id) !== false)
    {
        return this.instance().setLayerEnabledById(id, state)
    }
    else
    {
        return this.instance().setLayerEnabledByDatabaseId(id, state)
    }
};

/**
* Get the current coordinates
*
* @method
* @return string
*/
ivj.prototype.get_coordinates = function()
{
    ivj.log('Method: get_coordinates');

    //get coordinates
    var lat = Math.round(this.instance().getOrbitView().getCenterPosition().getLatitude().degrees*1000000)/1000000;
    var lon = Math.round(this.instance().getOrbitView().getCenterPosition().getLongitude().degrees*1000000)/1000000;
    var zoom = Math.round(this.instance().getOrbitView().getZoom());
    var head = Math.round(this.instance().getOrbitView().getHeading().degrees*100)/100;
    var pitch = Math.round(this.instance().getOrbitView().getPitch().degrees*100)/100;
    return 'Coordinates' + ';' + lat + ';' + lon + ';' + zoom + ';' + head + ';' + pitch;
};

/**
* Load a KML file
*
* @method
* @return void
*/
ivj.prototype.load_kml = function(name,uri)
{
    ivj.log('Method: load_kml');
    this.instance().addKmlLayer(name,uri);
};

/**
 *Run a script made up of multiple goto locations
 *
 *@method
 *@return void
 */
ivj.prototype.run_script = function()
{
    if(this.script)
    {
        this.script.play(this.id,true);
    }
}

/**
 *Load a script into an array for running
 *
 *@method
 *@return void
 */
ivj.prototype.load_script = function(object_script)
{
    this.script = object_script;
}

/**
 *Pause a script
 *
 *@method
 *@return void
 */
ivj.prototype.pause = function()
{
    if(this.script)
    {
        this.script.pause(this.id);
    }
}

/**
 *Load a script into an array for running
 *
 *@method
 *@return void
 */
ivj.prototype.load_script_from_string = function(string_script)
{
    this.script = new ivj_script(this.id,string_script);
}


/**
* Set the applet position based on fullscreen mode and placeholder position
*
* @method
* @return void
*/
ivj.prototype.position = function()
{
    ivj.log("Method: position");

    if (this.full_screen)
    {
        this.scroll_y = $(window).scrollTop();
        this.object.height($(window).height()).width($(window).width()).css({
            top: (this.scroll_y+1)+'px',
            left: 0
        });
        window.scroll(0,this.scroll_y+1);
    }
    else
    {
        this.object.width(this.width).height(this.height).css({
            top:this.offset.top + 'px',
            left:this.offset.left + 'px'
        });
        window.scroll(0, this.scroll_y);
    }
}

/**
 * Get the current instance of the IVJ object, eithe rold style or new style.
 *
 * @method
 * @return {object}
 */
ivj.prototype.instance = function()
{
    var theApplet = this.object[0];
    try
    {
        theApplet = theApplet.getSubApplet();
    }
    catch (e)
    {
        ivj.log("Failed to get sub applet, using object reference. " + theApplet.id);
    }
    return theApplet;
}

/**
 * Callback Router Function
 * Called by IVJ when an instance is initialized.
 */
function appletInit(id) 
{
    ivj.log(id + ' appletInit');
    if(ivj.instances[id]) ivj.instances[id].appletInit();
}

/**
 * Callback Router Function
 * Called by IVJ when an applet is started.
 */
function appletStart(id) 
{
    ivj.log(id + ' appletStart');
    if(ivj.instances[id]) ivj.instances[id].appletStart();
}

/**
 * Callback Router Function
 * Called by IVJ when an applet is closed
 */
function appletStop(id) 
{
    ivj.log(id + ' appletStop');
    if(ivj.instances[id]) ivj.instances[id].appletStop();
}

/**
 * Callback Router Function
 * Called by IVJ when an applet's "full screen" button is clicked.
 */
function appletFullscreen(id, state)
{
    ivj.log(id + ' appletFullscreen');
    if(ivj.instances[id]) ivj.instances[id].appletFullscreen(state);
}

/**
 * Callback link handler
 */
function follow_link(url)
{
    if(url.indexOf("?") !== -1)
    {
        url_options = $.extend({
            'popup':'false',
            'width':'500',
            'height':'300'
        },urlQueryToObject(url));
        if(url_options.popup == 'true')
        {
            window.open(
                url,
                "ivj_popup",
                "status=no,toolbar=no,location=no,menubar=no," +
                "directories=no,resizable=yes,scrollbars=no,personalbar=no,height=" +
                url_options.height+",width="+url_options.width);
        }
        else window.location.href = url;
    }
    else window.location.href = url;
}

/**
 * Get query string from URL
 */
function urlQueryToObject(s){
    var query = {};
    var pairs = s.split("?");
    pairs = pairs[1].split("&");
    for ( i in pairs )
    {
        var keyval = pairs[ i ].split( "=" );
        query[ keyval[0] ] = keyval[1];
    }
    return query;
}

//------------------------------------------------------------------------------Scripts

/**
* @classDescription Script object for animating IVJ
* @param input_script string script
* @param input_settings object settings
*/
function ivj_script(input_script,input_settings)
{
    try
    {
        this.settings = {
            'default_delay':5000,
            'repeat':1
        }
        this.locations = [];
        this.pointer = 0;
        this.repeats = 0;
        this.paused = false;

        //setup
        if(input_script) this.locations = input_script.split('|');
        if(input_settings) this.settings = $.extend(this.settings,input_settings);
    }
    catch(err)
    {
        alert(err);
    }
}

/**
 *@method
 *Adds a location to the script queue
 *
 *@param location string location (semicolon delimited)
 *@returns void
 */
ivj_script.prototype.add_location = function(location)
{
    this.locations.push(location);
};

/**
 *@method
 *Removes all items from the script queue
 *
 *@returns void;
 */
ivj_script.prototype.clear = function()
{
    this.locations = [];
};

/**
 *@method
 *Resets the script counters (start the script over)
 *
 *@returns void
 */
ivj_script.prototype.reset = function()
{
    this.pointer = 0;
    this.repeats = 0;
}

/**
 *@method
 *Plays the current script
 *
 *@param instance_id string id of the inteleview instance to play on
 *@param resume boolean indicator to override "paused" state
 *@returns void
 */
ivj_script.prototype.play = function(instance_id,resume)
{
    ivj.log("Play Script");
    if(resume) this.paused = false;
    try
    {
        if(!instance_id) throw("Script must play on an instance!");
        var next = this.get_next(instance_id);
        if(next!==false)
        {
            //goto next location
            ivj.instances[instance_id].go_to(next.location);

            //setup next call
            thisObj = this;
            setTimeout(function() {
                thisObj.play.call(thisObj,instance_id);
            }, parseInt(next.delay));
        }
    }
    catch(err)
    {
        alert(err);
    }
};

/**
 *@method
 *Get the next location from the script
 *
 *@caller play()
 *@param instance_id string id of the inteleview instance the script is being played on
 *@returns object
 */
ivj_script.prototype.get_next = function(instance_id)
{
    if(!this.paused)
    {
        if(this.locations.length > 0)
        {
            if(this.pointer==this.locations.length && this.settings.repeat>this.repeats)
            {
                this.pointer = 0;
                this.repeats++;
            }
            if(this.locations[this.pointer])
            {
                this.pointer++;
                return {
                    'location':this.locations[this.pointer-1],
                    'delay':this.settings.default_delay
                };
            }
            else return false;
        }
        else return false;
    }
    else return false;
}

/**
 *@method
 *Pause the script immediately.
 *
 *@returns void
 */
ivj_script.prototype.pause = function(instance_id)
{
    ivj.instances[instance_id].go_to(ivj.instances[instance_id].get_coordinates());
    this.paused = true;
};

/**
 *@static propetry
 *Default scripts
 */
ivj_script.default_scripts = {
    'orbit':new ivj_script()
};

/**
 *@Method Override
 *Change the get_next method to calculate the next position instead of fetching
 *it from the queue
 *
 *@param instance_id
 *@returns object
 */
ivj_script.default_scripts.orbit.get_next = function(instance_id)
{
    if(!this.paused)
    {
        var params = ivj.instances[instance_id].get_coordinates().split(';');
        params[1]=parseFloat(params[1]);
        params[2]=parseFloat(params[2]);
        params[2] += 36;
        params[1] = params[1]/1.2;

        return {
            'location':params.join(';'),
            'delay':5000
        };
    }
    else return false;
}
