
//----------------------------------------
//DEFINES
//----------------------------------------
var ROOT_NODE_ID = -1000;   	// the invisible root node at 0,0
var USER_NODE_ID = -1001;   	// the sphere+camera
var SCENEROOT_NODE_ID = -1002;
var SPHERE_NODE_ID = -1003;     // the sphere node for the current scene/frame
var UNSIGNED_ID = -2000; 	// someone didn't have an id.. for example the dummy load node.
		
var NODE_TYPE_GEO = "GeoNode";  		// node without a type
var NODE_TYPE_ROOT = "GeoRoot";  		// the root node... invisible at 0,0.  everything else is it's child
var NODE_TYPE_USER = "GeoUser";  		// camera + sphere
var NODE_TYPE_IMAGE = "GeoImage";       // plane (can be billboard)
var NODE_TYPE_TEXT = "GeoText";        // text node
var NODE_TYPE_LABEL = "GeoLabel";       // text label in 2D, but positioned in 3D, used for street labels
var NODE_TYPE_VIDEO = "GeoVideo";       // video node
var NODE_TYPE_LINE = "GeoLine";

var TWEEN_OBJECT_SPHERE = "TweenObjectSphere";
var TWEEN_OBJECT_CAMERA = "TweenObjectCAMERA";
var TWEEN_OBJECT_TEXTURE = "TweenObjectTexture";
var TWEEN_EASE_IN = "TweenEaseIn";
var TWEEN_EASE_OUT = "TweenEaseOut";
var TWEEN_EASE_LINEAR = "TweenEaseLinear";
var TWEEN_TYPE_FILTER = "TweenTypeFilter";
var TWEEN_TYPE_NORMAL = "TweenTypeNormal";

var NODE_STATE_NORMAL = 0;
var NODE_STATE_HOVER = 1;
var NODE_STATE_DOWN = 2;

var VIDEO_STATE_UNINITIALIZED = 0;
var VIDEO_STATE_STOPPED = 1;
var VIDEO_STATE_PAUSED = 2;
var VIDEO_STATE_PLAYING = 3;
var VIDEO_STATE_SEEKING = 4;
var VIDEO_STATE_BUFFERING = 5;
var VIDEO_STATE_STALLED = 6;
var VIDEO_STATE_LOADED = 7;
var VIDEO_STATE_LOAD_FAILED = 8;

var ERROR_QUERY_LOCATION = 0;
var ERROR_LOAD_STILL = 1;
var ERROR_LOAD_VIDEO = 2;
var ERROR_LOAD_DATA = 3;
var ERROR_LOAD_GEOPOINT = 4;

var VIDEO_EVENT_START = "VIDEO_START";
var VIDEO_EVENT_FINISHED = "VIDEO_FINISHED";
var VIDEO_EVENT_ERROR_FAILED = "VIDEO_ERROR_FAILED";
var VIDEO_EVENT_ERROR_NOT_FOUND = "VIDEO_ERROR_NOT_FOUND";
var VIDEO_EVENT_PAUSE = "VIDEO_PAUSE";
var VIDEO_EVENT_PLAY = "VIDEO_PLAY";
var VIDEO_EVENT_CLOSE = "VIDEO_CLOSE";


var DefaultRange = 50;
var DefaultPoiRange = 50;
var DefaultLimit = 50;

//var g_imSceneNodes = new Array();
var g_imDebug = false;

var g_imPlayerArray = new Array();
var g_imPlayerInstanceCount = 0;
var g_imPlayerPath = '';

function getPlayer(playerId) {
    return g_imPlayerArray[playerId];
}

function getFlashMovie(movieName) {
    var isIE = navigator.appName.indexOf("Microsoft") != -1;
    return (isIE) ? window[movieName] : document.getElementById(movieName);
}

function SceneNode(nodeId, nodeType, xmlData)// xmldata is a string
{
    this.nodeId = nodeId;
    //this.xmlData= new XML(xmlData);
    this.type = nodeType;

    //this.getLongitude = function getLongitude()
    //{
    //	return getPlayer().getLongitude(this.nodeId);
    //}

}


function sceneNode_onLoad(playerId, nodeId, script, nodeType, xmlData) {

    player = getPlayer(playerId);
    augment = player;

    try {
        eval(script);
    }
    catch (e) {
        if (g_imDebug) {
            alert("sceneNode_onLoad error parsing: " + e);
        }
    }
}


function sceneNode_onMouseOut(playerId, nodeId, script) {
    player = getPlayer(playerId);
    augment = player;

    player.debugTrace("sceneNode_onMouseOut(): nodeID=" + nodeId);

    if (!player.onNodeMouseOut(nodeId)) {
        return;
    }

    try {
        eval(script);
    }
    catch (e) {
        if (g_imDebug) {
            alert("sceneNode_onMouseOut error parsing: " + e);
        }
    }
}

function sceneNode_onMouseOver(playerId, nodeId, script) {
    player = getPlayer(playerId);
    augment = player;

    player.debugTrace("sceneNode_onMouseOver(): nodeID=" + nodeId);

    if (!player.onNodeMouseOver(nodeId)) {
        return;
    }

    try {
        eval(script);
    }
    catch (e) {
        if (g_imDebug) {
            alert("sceneNode_onMouseOver error parsing: " + e);
        }
    }
}

function sceneNode_onClick(playerId, nodeId, script) {

    player = getPlayer(playerId);
    augment = player;

    player.debugTrace("sceneNode_onClick(): nodeID=" + nodeId);

    if (!player.onNodeMouseClick(nodeId)) {
        return;
    }

    if ((script != "") && (script != null)) {
        try {
            eval(script);
        }
        catch (e) {
            if (g_imDebug) {
                alert("sceneNode_onClick error parsing: " + e);
            }
        }
    }
}


function button_onClick(playerId, buttonId, script) {

    player = getPlayer(playerId);
    augment = player;

    //alert("button_onClick(): TEST");

    player.debugTrace("button_onClick(): buttonID=" + buttonId);

    //node = g_imSceneNodes[nodeId];

    try {
        eval(script);
    }
    catch (e) {
        if (g_imDebug) {
            alert("button_onClick error parsing: " + e);
        }
    }
}


function Flash_Alert(txt) {
    alert(txt);
}

//----------------------------------------
// PLAYER INITIALIZATION SUPPORT
//----------------------------------------
function imSetPlayerPath(url) {
    g_imPlayerPath = url;
}


//----------------------------------------
// IM Button Object
//----------------------------------------
/**
* @class
* @constructor
*/
function imButton(id) {

    this.id = id;
    this.playerId = 0;
    this.x = 0;
    this.y = 0;
    this.normalUrl = null;
    this.hoverUrl = null;

    this.onClick = function() {
    }

    this.setPos = function(x, y) {
        getFlashMovie(this.playerId).setButtonPos(this.id, x, y);
        this.x = x;
        this.y = y;
    }
}

//----------------------------------------
// Proxy Object
//----------------------------------------
/**
* @class
* @constructor
*/
function imPlayer(element, configPath) {

    this.parent = element;
    this.id = 'imp_inst_' + g_imPlayerInstanceCount++;
    this.parent.innerHTML = InsertPlayerString(this.id, '100%', '100%', "transparent", configPath);
    this.isLoaded = false;

    g_imPlayerArray[this.id] = this;

    this.buttons = new Array();

    ///////////////////////////////////////////////////
    // Core player functionality
    ///////////////////////////////////////////////////

    this.getTotalMemory = function() {
        return getFlashMovie(this.id).getTotalMemory();
    }

    this.loadVideo = function(url, startTime, startPaused) {
        getFlashMovie(this.id).loadVideo(url, startTime, startPaused);
    }

    this.loadLiveStream = function(rtmpUrl, videoName) {
        getFlashMovie(this.id).loadLiveStream(rtmpUrl, videoName);
    }

    this.loadVideoSource = function(videoSourceId, startTime, startPaused) {
        getFlashMovie(this.id).loadVideoSource(videoSourceId, startTime, startPaused);
    }

    this.loadStill = function(url, heading) {
        getFlashMovie(this.id).loadStill(url, heading);
    }

    this.debugTrace = function(strTrace) {
        getFlashMovie(this.id).debugTrace(strTrace);
    }

    this.destroyScene = function() {
        getFlashMovie(this.id).destroyScene();
    }

    this.setVideoQualityPreference = function(quality) {
        getFlashMovie(this.id).setVideoQualityPreference(quality);
    }

    this.setWindowStyle = function(style) {
        document.getElementById(this.id).wmode = style;
    }
    
    //this.getMediaUrl = function(){
    //	return getFlashMovie(this.id).getMediaUrl();
    //}

    this.getMediaDuration = function() {
        return getFlashMovie(this.id).getMediaDuration();
    }

    this.getMediaTime = function() {
        return getFlashMovie(this.id).getMediaTime();
    }

    this.getMediaSourceId = function() {
        return getFlashMovie(this.id).getMediaSourceId();
    }

    this.getMediaSourceFrameId = function() {
        return getFlashMovie(this.id).getMediaSourceFrameId();
    }

    this.getMediaSourceStillId = function() {
        return getFlashMovie(this.id).getMediaSourceStillId();
    }

    this.getMediaSourceFrameTime = function() {
        return getFlashMovie(this.id).getMediaSourceFrameTime();
    }    

    this.setMediaTime = function(time) {
        getFlashMovie(this.id).setMediaTime(time);
    }

    this.setEventInterval = function(time) {
        getFlashMovie(this.id).setEventInterval(time);
    }

    this.getEventInterval = function() {
        getFlashMovie(this.id).getEventInterval();
    }

    //this.getMediaState = function(){
    //	return getFlashMovie(this.id).getMediaState();
    //}

    this.pauseVideo = function() {
        getFlashMovie(this.id).pauseVideo();
    }

    this.playVideo = function() {
        getFlashMovie(this.id).playVideo();
    }

    this.play2DVideo = function(url, id, screenX, screenY, videoWidth, videoHeight) {
        getFlashMovie(this.id).play2DVideo(url, id, screenX, screenY, videoWidth, videoHeight);
    }

    this.remove2DVideo = function(id) {
        getFlashMovie(this.id).remove2DVideo(id);
    }

    this.isVideoPlaying = function() {
        return getFlashMovie(this.id).isVideoPlaying();
    }

    this.addText2D = function(text, id, font, size, color, x, y) {
        getFlashMovie(this.id).addText2D(text, id, font, size, color, x, y);
    }

    this.addText3D = function(text, longitude, latitude, altitude, clickEnabled) {
        return getFlashMovie(this.id).addText3D(text, "", "", "", longitude, latitude, altitude, clickEnabled);
    }

    this.removeText = function(id) {
        getFlashMovie(this.id).removeText(id);
    }

    // fadeDelay and pulseSpeed are in milliseconds (1000 = 1 second)
    this.initOverlay = function(imageURL, fadeTime, pulseSpeed) {
        getFlashMovie(this.id).initOverlay(imageURL, fadeTime, pulseSpeed);
    }

    this.setOverlayEnabled = function(show) {
        getFlashMovie(this.id).setOverlayEnabled(show);
    }

    this.getOverlayEnabled = function(show) {
        return getFlashMovie(this.id).getOverlayEnabled();
    }

    this.addPolicyFile = function(policyFile) {
        getFlashMovie(this.id).addPolicyFile(policyFile);
    }

    this.togglePlayPause = function() {
        getFlashMovie(this.id).togglePlayPause();
    }

    this.exitFullScreen = function() {
        getFlashMovie(this.id).exitFullScreen();
    }

    this.loadData = function(url, resetView) {
        getFlashMovie(this.id).loadData(url, resetView);
    }

    this.setData = function(xml, resetView) {
        getFlashMovie(this.id).setData(xml, resetView);
    }

    this.setUserConfigData = function(key, value) {
        getFlashMovie(this.id).setUserConfigData(key, value);
    }

    this.getUserConfigData = function(key) {
        return getFlashMovie(this.id).getUserConfigData(key);
    }

    this.getVersion = function() {
        return getFlashMovie(this.id).getVersion();
    }

    this.getWidth = function() {
        return getFlashMovie(this.id).getWidth();
    }

    this.getHeight = function() {
        return getFlashMovie(this.id).getHeight();
    }

    this.getLoadDataUrl = function() {
        return getFlashMovie(this.id).getLoadDataUrl();
    }

    this.getLastStillUrl = function() {
        return getFlashMovie(this.id).getLastStillUrl();
    }

    this.getLastVideoUrl = function() {
        return getFlashMovie(this.id).getLastVideoUrl();
    }

    this.isVideoLoaded = function() {
        return getFlashMovie(this.id).isVideoLoaded();
    }

    this.isMouseDown = function() {
        return getFlashMovie(this.id).isMouseDown();
    }

    this.resize = function() {
        //getFlashMovie(this.id).style.width = this.parent.style.width;
        //getFlashMovie(this.id).style.height = this.parent.style.height;
    }

    this.getFov = function() {
        return getFlashMovie(this.id).getFov();
    }

    this.setFov = function(fov) {
        getFlashMovie(this.id).setFov(fov);
    }

    this.setGuiParam = function(param, newValue) {
        getFlashMovie(this.id).setGuiParam(param, newValue);
    }

    this.getGuiElementVisible = function(name) {
        return getFlashMovie(this.id).getGuiElementVisible(name);
    }

    this.setGuiElementVisible = function(name, visible) {
        getFlashMovie(this.id).setGuiElementVisible(name, visible);
    }

    this.getGuiElementEnabled = function(name) {
        return getFlashMovie(this.id).getGuiElementEnabled(name);
    }

    this.setGuiElementEnabled = function(name, enabled) {
        getFlashMovie(this.id).setGuiElementEnabled(name, enabled);
    }

    this.makeURL = function(urlId, path) {
        return getFlashMovie(this.id).makeURL(urlId, path);
    }

    this.getCurrentPlaylistIndex = function() {
        return getFlashMovie(this.id).getCurrentPlaylistIndex();
    }

    this.getPlaylistCount = function() {
        return getFlashMovie(this.id).getPlaylistCount();
    }

    this.isPlaylistLooping = function() {
        return getFlashMovie(this.id).isPlaylistLooping();
    }

    this.refreshSkin = function() {
        getFlashMovie(this.id).refreshSkin();
    }
    
    this.setSkin = function(skinId) {
        getFlashMovie(this.id).setSkin(skinId);
    }

    this.setVideoDescription = function(desc) {
        getFlashMovie(this.id).setVideoDescription(desc);
    }

    this.setVideoName = function(name) {
        getFlashMovie(this.id).setVideoName(name);
    }

    this.setVideoNameAndDescription = function(name, desc) {
        getFlashMovie(this.id).setVideoNameAndDescription(name, desc);
    }


    this.getAddressString = function() {
        return getFlashMovie(this.id).getAddressString();
    }

    this.getAddress = function() {
        return getFlashMovie(this.id).getAddress();
    }
    this.setAddress = function(number) {
        getFlashMovie(this.id).setAddress(number);
    }

    this.getStreet = function() {
        return getFlashMovie(this.id).getStreet();
    }
    this.setStreet = function(street) {
        getFlashMovie(this.id).setStreet(street);
    }

    this.getCity = function() {
        return getFlashMovie(this.id).getCity();
    }
    this.setCity = function(city) {
        getFlashMovie(this.id).setCity(city);
    }

    this.getState = function() {
        return getFlashMovie(this.id).getState();
    }
    this.setState = function(state) {
        getFlashMovie(this.id).setState(state);
    }

    this.getZip = function() {
        return getFlashMovie(this.id).getZip();
    }
    this.setZip = function(zip) {
        getFlashMovie(this.id).setZip(zip);
    }

    this.clearAddress = function() {
        getFlashMovie(this.id).clearAddress();
    }


    // Core player events.
    this.onLoad = function() {
    }

    this.onViewHeadingChange = function(heading, pitch) {
    }

    this.onVideoStateChange = function(newState) {
        //alert("onVideoStateChange(): newState: " + newState);
    }

    this.onVideoLoaded = function(url, videoWidth, videoHeight) {
        //alert("onVideoLoaded(): url: " + url);
    }

    this.onVideoClosed = function() {
        //alert("onVideoClosed()");
    }

    this.onClearSceneBegin = function() {
        //alert("onClearSceneBegin()");
    }

    this.onClearSceneEnd = function() {
        //alert("onClearSceneEnd()");
    }

    this.onGeoPointLoaded = function(distance, latitude, longitude, altitude) {
        //alert("onGeoPointLoaded(): distance: " + distance + " lat: " + latitude + " long: " + longitude + " alt: " + altitude );
    }

    this.onImageNodeImageLoaded = function(nodeId, state, url) {
        //alert("onImageNodeImageLoaded(): nodeId: " + nodeId + " state: " + state + " url: " + url);
    }

    this.onNodeRemoved = function(nodeId) {
        //alert("onNodeRemoved(): nodeId: " + nodeId );
    }

    this.onNodeMouseDown = function(nodeId, u, v) {
        //alert("onNodeMouseDown(): nodeId: " + nodeId );
    }

    this.onNodeMouseUp = function(nodeId, u, v) {
        //alert("onNodeReleased(): nodeId: " + nodeId );
    }

    this.onQueryNodeForRemoval = function(nodeId) {
        //alert("onQueryNodeForRemoval(): nodeId: " + nodeId );
        return true;
    }

    this.onQueryGeoLabelForRemoval = function(nodeId, label) {
        //alert("onQueryGeoLabelForRemoval(): nodeId: " + nodeId );
        return true;
    }

    this.onAddressDataSet = function(streetNum, street, city, state, zip) {            
    }

    this.onError = function(errorID, errorMsg) {
        //alert("onError() code: " + errorID);
    }

    this.onMediaClicked = function(time, u, v) {
        //alert("onMediaClicked() time: " + time + " (u,v): " + u + ", " + v);
    }

    this.onMediaTimeChange = function(time) {
        //alert("onMediaTimeChange() time: " + time);
    }

    this.onStillLoaded = function(url) {
        //alert("onStillLoaded(): url: " + url);
    }

    this.onResize = function(stageWidth, stageHeight) {
        //alert("onResize(): width: " + stageWidth + " height: " + stageHeight);
    }

    this.onVideoDescriptionLoaded = function(videoId, name, desc) {
        //alert("onVideoDescriptionLoaded(): name: " + name);
    }

    ///////////////////////////////////////////////////
    // Augumentation Functionality
    ///////////////////////////////////////////////////


    this.getRequestParameter = function(requestId, parameterName) {
        return getFlashMovie(this.id).getRequestParameter(requestId, parameterName);
    }

    this.setRequestParameter = function(requestId, parameterName, newValue) {
        getFlashMovie(this.id).setRequestParameter(requestId, parameterName, newValue);
    }

    this.getCustomerKey = function() {
        return getFlashMovie(this.id).getCustomerKey();
    }

    this.setCustomerKey = function(key) {
        getFlashMovie(this.id).setCustomerKey(key);
    }

    this.setStillHeading = function(heading) {
        getFlashMovie(this.id).setStillHeading(heading);
    }

    this.getStillHeading = function() {
        return getFlashMovie(this.id).getStillHeading();
    }

    this.queryLocation = function(longitude, latitude, altitude, imageTypes, resetView) {
        getFlashMovie(this.id).queryLocation(longitude, latitude, altitude, imageTypes, resetView);
    }

    this.clearScene = function() {
        getFlashMovie(this.id).clearScene();
    }

    this.getRelativeLocation = function(longitude, latitude, altitude, x, y, z) {
        return getFlashMovie(this.id).getRelativeLocation(longitude, latitude, altitude, x, y, z);
    }

    this.getDistance = function(lat1, long1, alt1, lat2, long2, alt2) {
        return getFlashMovie(this.id).getDistance(lat1, long1, alt1, lat2, long2, alt2);
    }

    // Line support
    this.addLineNode = function(color, alpha, thickness) {
        return getFlashMovie(this.id).addLineNode(color, alpha, thickness);
    }

    this.addLineNodePoint = function(nodeId, lng, lat, alt) {
        return getFlashMovie(this.id).addLineNodePoint(nodeId, lng, lat, alt);
    }

    this.removeLineNodePoint = function(nodeId, pointIndex) {
        return getFlashMovie(this.id).removeLineNodePoint(nodeId, pointIndex);
    }

    this.getLineNodePointCount = function(nodeId) {
        return getFlashMovie(this.id).getLineNodePointCount(nodeId);
    }

    this.clearLineNodePoints = function(nodeId) {
        getFlashMovie(this.id).clearLineNodePoints(nodeId);
    }

    this.getLineNodeColor = function(nodeId) {
        return getFlashMovie(this.id).getLineNodeColor(nodeId);
    }

    this.setLineNodeColor = function(nodeId, color) {
        getFlashMovie(this.id).setLineNodeColor(nodeId, color);
    }

    this.getLineNodeAlpha = function(nodeId) {
        return getFlashMovie(this.id).getLineNodeAlpha(nodeId);
    }

    this.setLineNodeAlpha = function(nodeId, alpha) {
        getFlashMovie(this.id).setLineNodeAlpha(nodeId, alpha);
    }

    this.getLineNodeThickness = function(nodeId) {
        return getFlashMovie(this.id).getLineNodeThickness(nodeId);
    }

    this.setLineNodeThickness = function(nodeId, thickness) {
    getFlashMovie(this.id).setLineNodeThickness(nodeId, thickness);
    }

    // Augment Events
    this.onLocationChange = function(longitude, latitude, altitude) {
    }

    this.onAnglesChange = function(yaw, pitch, roll) {
    }

    this.onDataLoad = function() {
    }

    this.onMouseUp = function() {
    }

    this.onMouseDown = function() {
    }

    this.onNodeLoad = function(nodeId) {
        return true;
    }

    this.onNodesLoaded = function() {
        //alert("onNodesLoaded() All nodes have been loaded");
    }
    
    this.onNodeMouseOver = function(nodeId) {
        //alert("over: " + nodeId);
        return true;
    }

    this.onNodeMouseClick = function(nodeId) {
        //alert("click: " + nodeId);
        return true;
    }

    this.onNodeMouseOut = function(nodeId) {
        //alert("out: " + nodeId);
        return true;
    }

    this.setDrawDistance = function(distance) {
        getFlashMovie(this.id).setDrawDistance(distance);
    }

    this.getDrawDistance = function() {
        return getFlashMovie(this.id).getDrawDistance();
    }

    ///////////////////////////////////////////////////
    // Dynamic Button Functionality
    ///////////////////////////////////////////////////

    this.addButton = function(buttonId, normalUrl, hoverUrl, x, y, useHand) {
        if (!getFlashMovie(this.id).addButton(buttonId, normalUrl, hoverUrl, x, y, useHand)) {
            return null;
        }

        var B = new imButton(buttonId);
        this.buttons[buttonId] = B;

        B.playerId = this.id;
        B.x = x;
        B.y = y;
        B.normalUrl = normalUrl;
        B.hoverUrl = hoverUrl;

        return B;
    }

    this.removeButton = function(buttonId) {
        getFlashMovie(this.id).removeButton(buttonId);
        this.buttons[buttonId] = null;
        // TODO: create array remove funciton, javascript 
        // does not come with one by default.. sheesh.
    }

    this.onButtonClick = function(buttonId) {

    }

    ///////////////////////////////////////////////////
    // Augumentation.node Functionality
    ///////////////////////////////////////////////////


    this.addImageNode = function(parentId,
	                            longitude,
								latitude,
								altitude,
								scale,
								image_normal,
								image_hover,
								billboard, useHand, yaw, pitch, roll) {

        return getFlashMovie(this.id).addImageNode(parentId,
	                                        longitude,
								            latitude,
								            altitude,
								            scale,
								            image_normal,
								            image_hover,
								            billboard, useHand, yaw, pitch, roll);
    }

    // This adds a screen transition between still screens.  Check the defines above using TWEEN_* constants.
    this.addTransition = function( tweenObject, tweenParam, 
                        tweenValue, tweenTime, tweenDelay, tweenEasing, tweenType) {

        return getFlashMovie(this.id).addTransition(tweenObject, tweenParam, 
                                                    tweenValue, tweenTime, tweenDelay, tweenEasing, tweenType);
    }

    this.clearTransitions = function() {

        return getFlashMovie(this.id).clearTransitions();
    }
		
    this.setScale = function(nodeId, scale) {
        getFlashMovie(this.id).setScale(nodeId, scale);
    }

    this.setImageNodeTexture = function(nodeId, state, url) {
        getFlashMovie(this.id).setImageNodeTexture(nodeId, state, url);
    }

    this.getImageNodeTextureUrl = function(nodeId, state) {
        return getFlashMovie(this.id).getImageNodeTextureUrl(nodeId, state);
    }

    this.removeGeoNode = function(nodeId) {
        getFlashMovie(this.id).removeGeoNode(nodeId);
    }

    this.setLocation = function(nodeId, longitude, latitude, altitude) {
        getFlashMovie(this.id).setLocation(nodeId, longitude, latitude, altitude);
    }

    this.useHandCursor = function(nodeId, useHand) {
        getFlashMovie(this.id).useHandCursor(nodeId, useHand);
    }

    this.getLocation = function(nodeId) {
        return getFlashMovie(this.id).getLocation(nodeId);
    }

    this.setRotations = function(nodeId, yaw, pitch, roll) {
        getFlashMovie(this.id).setRotations(nodeId, yaw, pitch, roll);
    }

    this.getRotations = function(nodeId) {
        return getFlashMovie(this.id).getRotations(nodeId);
    }

    this.getLongitude = function(nodeId) {
        return getFlashMovie(this.id).getLongitude(nodeId);
    }

    this.getLatitude = function(nodeId) {
        return getFlashMovie(this.id).getLatitude(nodeId);
    }

    this.getAltitude = function(nodeId) {
        return getFlashMovie(this.id).getAltitude(nodeId);
    }

    this.getYaw = function(nodeId) {
        return getFlashMovie(this.id).getYaw(nodeId);
    }

    this.setYaw = function(nodeId, newYaw) {
        getFlashMovie(this.id).setYaw(nodeId, newYaw);
    }

    this.getPitch = function(nodeId) {
        return getFlashMovie(this.id).getPitch(nodeId);
    }

    this.setPitch = function(nodeId, newPitch) {
        getFlashMovie(this.id).setPitch(nodeId, newPitch);
    }

    this.getRoll = function(nodeId) {
        return getFlashMovie(this.id).getRoll(nodeId);
    }

    this.setRoll = function(nodeId, newRoll) {
        getFlashMovie(this.id).setRoll(nodeId, newRoll);
    }

    this.getVisibility = function(nodeId) {
        return getFlashMovie(this.id).getVisibility(nodeId);
    }

    this.getNodeType = function(nodeId) {
        return getFlashMovie(this.id).getNodeType(nodeId);
    }

    this.getScale = function(nodeId) {
        return getFlashMovie(this.id).getScale(nodeId);
    }

    this.setVisibility = function(nodeId, visible) {
        getFlashMovie(this.id).setVisibility(nodeId, visible);
    }

    this.getTextNodeText = function(nodeId) {
        return getFlashMovie(this.id).getTextNodeText(nodeId);
    }

    this.setTextNodeText = function(nodeId, newText) {
        getFlashMovie(this.id).setTextNodeText(nodeId, newText);
    }

    this.setNodeProperty = function(nodeId, key, value) {
        getFlashMovie(this.id).setNodeProperty(nodeId, key, value);
    }

    this.getNodeProperty = function(nodeId, key) {
        return getFlashMovie(this.id).getNodeProperty(nodeId, key);
    }

    this.removeNodeProperty = function(nodeId, key) {
        getFlashMovie(this.id).removeNodeProperty(nodeId, key);
    }

    this.setNodeClickScript = function(nodeId, script) {
        return getFlashMovie(this.id).setNodeClickScript(nodeId, script);
    }

    this.getNodeClickScript = function(nodeId) {
        return getFlashMovie(this.id).getNodeClickScript(nodeId);
    }
    
    this.getStillProperty = function(nodeId, stillId, propertyName) {
        return getFlashMovie(this.id).getStillProperty(nodeId, stillId, propertyName);
    }

    this.getVideoProperty = function(nodeId, videoId, propertyName) {
        return getFlashMovie(this.id).getVideoProperty(nodeId, videoId, propertyName);
    }

    // Path Recording
    this.clearPathRecording = function() {
        getFlashMovie(this.id).clearPathRecording();
    }

    this.setPathRecordingKeyFrame = function(enabled){
        return getFlashMovie(this.id).setPathRecordingKeyFrame(enabled);
    }

    this.addPathRecordingKeyFrame = function(time, yaw, pitch, roll, fov, enabled) {
        return getFlashMovie(this.id).addPathRecordingKeyFrame(time, yaw, pitch, roll, fov, enabled);
    }

    this.removePathRecordingKeyFrame = function(frameId) {
        return getFlashMovie(this.id).removePathRecordingKeyFrame(frameId);
    }

    this.getPathRecordingKeyFrameCount = function() {
        return getFlashMovie(this.id).getPathRecordingKeyFrameCount();
    }

    this.getPathRecordingEnabled = function() {
        return getFlashMovie(this.id).getPathRecordingEnabled();
    }

    this.setPathRecordingEnabled = function(enabled) {
        return getFlashMovie(this.id).setPathRecordingEnabled(enabled);
    }

    this.onPathRecordingFrameReached = function(frameId) {
    }

    this.onPathRecordingFrameAdded = function(frame) {
    }

    this.onPathRecordingFrameRemoved = function(frame) {
    }

}


function player_onLoad(playerId) {
    g_imPlayerArray[playerId].isLoaded = true;
    g_imPlayerArray[playerId].resize();
    g_imPlayerArray[playerId].onLoad();
}

function player_onVideoStateChange(playerId, newState) {
    g_imPlayerArray[playerId].onVideoStateChange(newState);
}

function player_onStillLoaded(playerId, url) {
    g_imPlayerArray[playerId].onStillLoaded(url);
}

function player_onVideoLoaded(playerId, url, videoWidth, videoHeight) {
    g_imPlayerArray[playerId].onVideoLoaded(url, videoWidth, videoHeight);
}

function player_onVideoClosed(playerId) {
    g_imPlayerArray[playerId].onVideoClosed();
}

function player_onClearSceneBegin(playerId) {
    g_imPlayerArray[playerId].onClearSceneBegin();
}

function player_onClearSceneEnd(playerId) {
    g_imPlayerArray[playerId].onClearSceneEnd();
}

function player_onGeoPointLoaded(playerId, distance, latitude, longitude, altitude) {
    g_imPlayerArray[playerId].onGeoPointLoaded(url, distance, latitude, longitude, altitude);
}

function player_onImageNodeImageLoaded(playerId, nodeId, state, url) {
    g_imPlayerArray[playerId].onImageNodeImageLoaded(nodeId, state, url);
}

function player_onNodeLoad(playerId, nodeId) {
    return g_imPlayerArray[playerId].onNodeLoad(nodeId);
}

function player_onNodesLoaded(playerId) {
    return g_imPlayerArray[playerId].onNodesLoaded();
}

function player_onNodeRemoved(playerId, nodeId) {
    g_imPlayerArray[playerId].onNodeRemoved(nodeId);
}

function player_onNodeMouseDown(playerId, nodeId, u, v) {
    g_imPlayerArray[playerId].onNodeMouseDown(nodeId, u, v);
}

function player_onNodeMouseUp(playerId, nodeId, u, v) {
    g_imPlayerArray[playerId].onNodeMouseUp(nodeId, u, v);
}

function player_onQueryNodeForRemoval(playerId, nodeId) {
    return g_imPlayerArray[playerId].onQueryNodeForRemoval(nodeId);
}

function player_onQueryGeoLabelForRemoval(playerId, nodeId, label) {
    return g_imPlayerArray[playerId].onQueryGeoLabelForRemoval(nodeId, label);
}

function player_onAddressDataSet(playerId, streetNum, street, city, state, zip) {
    return g_imPlayerArray[playerId].onAddressDataSet(streetNum, street, city, state, zip);
}

function player_onError(playerId, errorID, errorMsg) {
    g_imPlayerArray[playerId].onError(errorID, errorMsg);
}

function player_onMediaClicked(playerId, time, u, v) {
    g_imPlayerArray[playerId].onMediaClicked(time, u, v);
}

function player_onMediaTimeChange(playerId, time) {
    g_imPlayerArray[playerId].onMediaTimeChange(time);
}

function player_onVideoDescriptionLoaded(playerId, videoId, name, desc) {
    g_imPlayerArray[playerId].onVideoDescriptionLoaded(videoId, name, desc);
}

function player_onViewHeadingChange(playerId, heading, pitch) {
    g_imPlayerArray[playerId].onViewHeadingChange(heading, pitch);
}

function player_onButtonClick(playerId, buttonId) {
    g_imPlayerArray[playerId].buttons[buttonId].onClick();
    g_imPlayerArray[playerId].onButtonClick(buttonId);
}

function player_onResize(playerId, stageWidth, stageHeight) {
    g_imPlayerArray[playerId].onResize(stageWidth, stageHeight);
}

function augment_onLocationChange(playerId, longitude, latitude, altitude) {
    g_imPlayerArray[playerId].onLocationChange(longitude, latitude, altitude);
}

function augment_onAnglesChange(playerId, yaw, pitch, roll) {
    g_imPlayerArray[playerId].onAnglesChange(yaw, pitch, roll);
}

function augment_onDataLoad(playerId) {
    g_imPlayerArray[playerId].onDataLoad();
}

function player_onMouseDown(playerId) {
    g_imPlayerArray[playerId].onMouseDown();
}

function player_onMouseUp(playerId) {
    g_imPlayerArray[playerId].onMouseUp();
}

function player_onPathRecordingFrameChange(playerId, frameId) {
    g_imPlayerArray[playerId].onPathRecordingFrameChange(frameId);
}

function player_onPathRecordingFrameAdded(playerId, frame) {
    g_imPlayerArray[playerId].onPathRecordingFrameAdded(frame);
}

function player_onPathRecordingFrameRemoved(playerId, frame) {
    g_imPlayerArray[playerId].onPathRecordingFrameRemoved(frame);
}

function augment_onGetDirectionsClicked(playerId, videoSourceId) {

    // This is activated when the user clicks the POI Get Directions button
    //alert('Get Directions Clicked! VideoID: ' + videoSourceId);  
}


//----------------------------------------
// Player Embed Support
//----------------------------------------
// Major version of Flash required
var requiredMajorVersion = 9;
// Minor version of Flash required
var requiredMinorVersion = 0;
// Minor version of Flash required
var requiredRevision = 0;


function AC_GenerateobjString(objAttrs, params, embedAttrs) {
    var str = '';
    if (isIE && isWin && !isOpera) {
        var i;

        str += '<object ';
        for (i in objAttrs)
            str += i + '="' + objAttrs[i] + '" ';
        str += '>';
        for (i in params)
            str += '<param name="' + i + '" value="' + params[i] + '" /> ';
        str += '</object>';
    } else {
        str += '<embed ';
        for (i in embedAttrs)
            str += i + '="' + embedAttrs[i] + '" ';
        str += '> </embed>';
    }

    return str;
}

function AC_FL_RunContentString() {
    var ret =
    AC_GetArgs
    (arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
     , "application/x-shockwave-flash"
    );
    return AC_GenerateobjString(ret.objAttrs, ret.params, ret.embedAttrs);
}

function InsertPlayerString(id, width, height, windowMode, configPath) {

    var Id = id;

    var hasProductInstall = DetectFlashVer(6, 0, 65);
    var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
    var Result = "";
    //var Result = "<script language='javascript'>";

    // Check to see if a player with Flash Product Install is available and the version does not meet the requirements for playback
    if (hasProductInstall && !hasRequestedVersion) {
        // MMdoctitle is the stored document.title value used by the installation process to close the window that started the process
        // This is necessary in order to close browser windows that are still utilizing the older version of the player after installation has completed
        // DO NOT MODIFY THE FOLLOWING FOUR LINES
        // Location visited after installation is complete if installation is required
        var MMPlayerType = (isIE == true) ? "ActiveX" : "PlugIn";
        var MMredirectURL = window.location;
        document.title = document.title.slice(0, 47) + " - Flash Player Installation";
        var MMdoctitle = document.title;

        Result += AC_FL_RunContentString(
					"src", g_imPlayerPath + "playerProductInstall",
					"base", g_imPlayerPath,
					"FlashVars", "MMredirectURL=" + MMredirectURL + '&MMplayerType=' + MMPlayerType + '&MMdoctitle=' + MMdoctitle + "",
					"width", width,
					"height", height,
					"align", "middle",
					"id", Id,
					"name", Id,
					"quality", "high",
					"allowFullScreen", "true",
					"menu", "false",
					"bgcolor", "#000000",
					"allowScriptAccess", "always",
					"type", "application/x-shockwave-flash",
					"pluginspage", "http://www.adobe.com/go/getflashplayer"
					);

    } else if (hasRequestedVersion) {
        // if we've detected an acceptable version
        // embed the Flash Content SWF when all tests are passed
        Result += AC_FL_RunContentString(
						"src", g_imPlayerPath + "IMPlayer",
						"base", g_imPlayerPath,
						"width", width,
						"height", height,
						"align", "middle",
						"id", Id,
						"name", Id,
						"quality", "high",
						"allowFullScreen", "true",
						"menu", "false",
						"bgcolor", "#000000",
						"flashvars", "playerid=" + Id + ((configPath==null)?"":"&config=" + configPath),
						"allowScriptAccess", "always",
						"type", "application/x-shockwave-flash",
						"pluginspage", "http://www.adobe.com/go/getflashplayer"						
						);

        //"wmode", windowMode, 

    } else {  // flash is too old or we can't detect the plugin
        Result = 'Alternate HTML content should be placed here. ' +
					'This content requires the Adobe Flash Player. ' +
					'<a href=http://www.adobe.com/go/getflash/>Get Flash</a>';
    }

    //Result += "</script>";

    Result += "<noscript>" +
				"<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' " +
				"id='" + Id + "' width='" + width + "' height='" + height + "' align='center' " +
				"codebase='http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab'>" +
				"<param name='movie' value='" + g_imPlayerPath + "IMPlayer.swf'/>" +
				"<param name='quality' value='high'/>" +
				"<param name='bgcolor' value='#000000'/>" +
				"<param name='allowScriptAccess' value='always'/>" +
				"<embed src='" + g_imPlayerPath + "IMPlayer.swf' quality='high' bgcolor='#000000' " +
				"width='" + width + "' height='" + height + "' name='" + Id + "' align='middle' " +
				((configPath==null)?"":"config='" + configPath + "'") +
				"play='true' " +
				"loop='false' " +
				"quality='high'	 " +
				"allowScriptAccess='always' " +
				"allowFullScreen='true' " +
				"menu='false' " +
				"type='application/x-shockwave-flash' " +
				"pluginspage='http://www.adobe.com/go/getflashplayer'>" +
				"base='" + g_imPlayerPath + "' " +
				"</embed>" +
				"</object>" +
				"</noscript>";

    return Result;
}



//-------------------------------------------------------------------------------------
//Adobe AC_OETags.js included for simplicity
//-------------------------------------------------------------------------------------
//Flash Player Version Detection - Rev 1.6
//Detect Client Browser type
//Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved.
var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;

function ControlVersion() {
    var version;
    var axo;
    var e;

    // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry

    try {
        // version will be set for 7.X or greater players
        axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
        version = axo.GetVariable("$version");
    } catch (e) {
    }

    if (!version) {
        try {
            // version will be set for 6.X players only
            axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");

            // installed player is some revision of 6.0
            // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
            // so we have to be careful. 

            // default to the first public version
            version = "WIN 6,0,21,0";

            // throws if AllowScripAccess does not exist (introduced in 6.0r47)		
            axo.AllowScriptAccess = "always";

            // safe to call for 6.0r47 or greater
            version = axo.GetVariable("$version");

        } catch (e) {
        }
    }

    if (!version) {
        try {
            // version will be set for 4.X or 5.X player
            axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
            version = axo.GetVariable("$version");
        } catch (e) {
        }
    }

    if (!version) {
        try {
            // version will be set for 3.X player
            axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
            version = "WIN 3,0,18,0";
        } catch (e) {
        }
    }

    if (!version) {
        try {
            // version will be set for 2.X player
            axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
            version = "WIN 2,0,0,11";
        } catch (e) {
            version = -1;
        }
    }

    return version;
}

//JavaScript helper required to detect Flash Player PlugIn version information
function GetSwfVer() {
    // NS/Opera version >= 3 check for Flash plugin in plugin array
    var flashVer = -1;

    if (navigator.plugins != null && navigator.plugins.length > 0) {

        if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {

            var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
            var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
            var descArray = flashDescription.split(" ");
            var tempArrayMajor = descArray[2].split(".");
            var versionMajor = tempArrayMajor[0];
            var versionMinor = tempArrayMajor[1];
            var versionRevision = descArray[3];

            if (versionRevision == "") {
                versionRevision = descArray[4];
            }

            if (versionRevision[0] == "d") {
                versionRevision = versionRevision.substring(1);
            } else if (versionRevision[0] == "r") {
                versionRevision = versionRevision.substring(1);

                if (versionRevision.indexOf("d") > 0) {
                    versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
                }
            }

            flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
        }
    }
    // MSN/WebTV 2.6 supports Flash 4
    else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
    // WebTV 2.5 supports Flash 3
    else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
    // older WebTV supports Flash 2
    else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
    else if (isIE && isWin && !isOpera) {
        flashVer = ControlVersion();
    }

    return flashVer;
}

//When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) {
    versionStr = GetSwfVer();
    if (versionStr == -1) {
        return false;
    } else if (versionStr != 0) {
        if (isIE && isWin && !isOpera) {
            // Given "WIN 2,0,0,11"
            tempArray = versionStr.split(" "); 	// ["WIN", "2,0,0,11"]
            tempString = tempArray[1]; 		// "2,0,0,11"
            versionArray = tempString.split(","); // ['2', '0', '0', '11']
        } else {
            versionArray = versionStr.split(".");
        }
        var versionMajor = versionArray[0];
        var versionMinor = versionArray[1];
        var versionRevision = versionArray[2];

        // is the major.revision >= requested major.revision AND the minor version >= requested minor
        if (versionMajor > parseFloat(reqMajorVer)) {
            return true;
        } else if (versionMajor == parseFloat(reqMajorVer)) {
            if (versionMinor > parseFloat(reqMinorVer))
                return true;
            else if (versionMinor == parseFloat(reqMinorVer)) {
                if (versionRevision >= parseFloat(reqRevision))
                    return true;
            }
        }
        return false;
    }
}

function AC_AddExtension(src, ext) {
    if (src.indexOf('?') != -1)
        return src.replace(/\?/, ext + '?');
    else
        return src + ext;
}

function AC_Generateobj(objAttrs, params, embedAttrs) {
    
    var str = '';
    var i;
    
    if (isIE && isWin && !isOpera) {
        str += '<object ';

        for (i in objAttrs)
            str += i + '="' + objAttrs[i] + '" ';

        str += '>';

        for (i in params)
            str += '<param name="' + i + '" value="' + params[i] + '" /> ';

        str += '</object>';
    } else {

        str += '<embed ';

        for (i in embedAttrs)
            str += i + '="' + embedAttrs[i] + '" ';

        str += '> </embed>';
    }

    document.write(str);
}

function AC_FL_RunContent() {

    var ret =
    AC_GetArgs
    (arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
      , "application/x-shockwave-flash"
    );

    AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_GetArgs(args, ext, srcParamName, classid, mimeType) {

    var ret = new Object();
    ret.embedAttrs = new Object();
    ret.params = new Object();
    ret.objAttrs = new Object();

    for (var i = 0; i < args.length; i = i + 2) {

        var currArg = args[i].toLowerCase();

        switch (currArg) {
            case "classid":
                break;
            case "pluginspage":
                ret.embedAttrs[args[i]] = args[i + 1];
                break;
            case "src":
            case "movie":
                args[i + 1] = AC_AddExtension(args[i + 1], ext);
                ret.embedAttrs["src"] = args[i + 1];
                ret.params[srcParamName] = args[i + 1];
                break;
            case "onafterupdate":
            case "onbeforeupdate":
            case "onblur":
            case "oncellchange":
            case "onclick":
            case "ondblClick":
            case "ondrag":
            case "ondragend":
            case "ondragenter":
            case "ondragleave":
            case "ondragover":
            case "ondrop":
            case "onfinish":
            case "onfocus":
            case "onhelp":
            case "onmousedown":
            case "onmouseup":
            case "onmouseover":
            case "onmousemove":
            case "onmouseout":
            case "onkeypress":
            case "onkeydown":
            case "onkeyup":
            case "onload":
            case "onlosecapture":
            case "onpropertychange":
            case "onreadystatechange":
            case "onrowsdelete":
            case "onrowenter":
            case "onrowexit":
            case "onrowsinserted":
            case "onstart":
            case "onscroll":
            case "onbeforeeditfocus":
            case "onactivate":
            case "onbeforedeactivate":
            case "ondeactivate":
            case "type":
            case "codebase":
                ret.objAttrs[args[i]] = args[i + 1];
                break;
            case "id":
            case "width":
            case "height":
            case "align":
            case "vspace":
            case "hspace":
            case "class":
            case "title":
            case "accesskey":
            case "name":
            case "tabindex":
                ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i + 1];
                break;
            default:
                ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i + 1];
        }
    }

    ret.objAttrs["classid"] = classid;

    if (mimeType)
        ret.embedAttrs["type"] = mimeType;

    return ret;
}



