//
// file: bscontact.js - object that handles Bitmanagement Contact Player specific functions
//
//   ABNet uses the methods here to get events and set events from 3d scene
//

// 0x1 - BS Contact, 0x2 - Vivaty, 0x3 - Shout3d, 0x4 - Cortona

ABNetApp.Scene = {
    _3dBrowser: 0x1,

    browser: null,
    b3DState: 0x0,

    X3D_LOADING: 0x0,
    X3D_LOADED: 0x01,
    X3D_LOADFAILED: 0x02
};

ABNetApp.Scene.setFieldValue = function(nodeName, fldName, fldValue) {
    var result = ABNetApp.Scene.browser.setNodeEventIn(nodeName, fldName, fldValue);
    if ( bDebug & DEBUG_3D ) {
	ABNetApp.Chat.append('3D>>:: set node=' + nodeName + ',fld=' + fldName + ',value=' + fldValue + ', ' + (result ? 'worked' : 'failed') );
    }
};

ABNetApp.Scene.getFieldValue = function(nodeName, fldName) {
    var result = ABNetApp.Scene.browser.getNodeEventOut(nodeName,fldName);
    if ( bDebug & DEBUG_3D ) {
	ABNetApp.Chat.append('3D<<:: get node=' + nodeName + ', fldName= ' + fldName + ', result = ' + result);
    }
    return result;
};

// base scene handlers for abnet

ABNetApp.sceneEventHandler = {

    // when our position changes save it off and send it to everyone else
    'onPC': function(e,v,t) {

        ABNetApp.User.me.p=v;
        ABNet.SendToAllExcept(ABNetApp.User.me.uniqID,'onPC',v);
    },

    // when our orientation changes, save it off and send it to everyone else
    'onOC': function(e,v,t) {

        ABNetApp.User.me.o=v;
        ABNet.SendToAllExcept(ABNetApp.User.me.uniqID,'onOC',v);
    },
  
    // when an avatar completes loading, deal with either ours or someone elses
    'onAvatarLoaded': function(e,v,t) {
	var userInfo = ABNetApp.Comm.personList[v];

        if ( userInfo ) {
	    if ( userInfo.isMe ) {
		// let the avatar setup happen on the next frame render (assumes 10/fps)
		setTimeout(function() { ABNetApp.Scene.setupMyAvatar(); }, 100);
	    }
	    else {
		ABNet.SendTo(v,'getLocation','where you are now');
	    }
        }
	else {
	    // if we get an avatar loaded notification for someone who left 
	    // since the request began, then we need to get rid of
	    // the avatar. However, we don't want to call right back
	    // into the 3d scene as it could cause a lag. We delay
	    // the request till the next frame render
	    
	    setTimeout(function() { ABNetApp.Scene.unloadAV(v) }, 100);
	}
    },

    // an object in the 3d scene can generate chat messages, we stuff our name on the front and
    // broadcast it to everyone else. We don't do a round trip, we just append it to chat
    'onSharedChat': function(e,v,t) {
        var msgFromScene=unescape(ABNetApp.User.me.username)+': '+v;

        ABNet.SendToAllExcept(ABNetApp.User.me.uniqID,e,escape(msgFromScene));
        ABNetApp.Chat.append(msgFromScene);
    }
};

// BS Contact onEvent handlers
// e = eventname, v = value, t = timestamp from 3d player
//

ABNetApp.Scene.onEvent = function(e,v,t) {
    // these are the inbound events from the 3d player | or some other scene handler
    
    if ( bDebug & DEBUG_3D ) { ABNetApp.Chat.append('3D<<:: event=' + e + ', value=' + v + ',ts=' + t);   }
    
    if ( ABNetApp.sceneEventHandler.hasOwnProperty(e) ) {
	ABNetApp.sceneEventHandler[e](e,v,t);
    }
    else {
        ABNet.SendToAllExcept(ABNetApp.User.me.uniqID,e,escape(v));
    }
};

ABNetApp.Scene.onReadyStateChange = function() {
  var cc3d = document.getElementById('CC3D');
  // ReadyState: 1 - loading, 2 - loaded, 3 - interactive, 4 - complete
  if ( cc3d && cc3d.ReadyState ) {
    //window.status='ReadyStateChange='+ ABNetApp.Scene.browser.ReadyState;
    if ( cc3d.ReadyState == 4 ) {
      if ( cc3d.url && cc3d.url.length > 0 && ABNetApp.Scene.browser ) {
	ABNetApp.Scene.b3DState=ABNetApp.Scene.X3D_LOADED;
	ABNetApp.Scene.setupABNetNodes(cc3d.url);
	ABNetApp.Comm.waitForConnect();
      }
      else {
	ABNetApp.Scene.b3DState=ABNetApp.Scene.X3D_LOADFAILED;
	status='[3d scene ' + ABNetApp.the3DURL + ' failed to load]';
      }
    }
    if ( cc3d.ReadyState == 1 ) {
      if ( ABNetApp.Comm.bABNetState == ABNetApp.Comm.STATE_JOINED ) {
	ABNetApp.Comm.bABNetState=ABNetApp.Comm.STATE_LEAVING;
	ABNet.Leave(ABNetApp.the3DURL);
      }
      ABNetApp.Scene.b3DState=ABNetApp.Scene.X3D_LOADING;
    }
  }
};

// -- loadAV - async avatar loading --

ABNetApp.Scene.loadAV = function(uniqID) {
  try {
    var userInfo=ABNetApp.Comm.personList[uniqID];

    vrml = 'DEF __av' + uniqID + ' ABNet_Avatar {\n' +
      '  uniqID "' + uniqID + '"\n' +
      '  url ["' + unescape(userInfo.avatarURL) + '"]\n' +
      '  nickname "' + userInfo.username + '"\n' +
      '  ABNet_S2 USE ABNet_S2\n' +
      '  me USE __av' + uniqID + '\n' +  
      '  isVisible ' + ( userInfo.isMe ? "FALSE" : "TRUE") + '\n' +
      '}\n' +
      '';

    if ( bDebug & DEBUG_3D ) { ABNetApp.Chat.append('3D>>: loadAV uniqID=' + uniqID + ']\nvrml=\n' + vrml); }

    ABNetApp.Scene.browser.addVrmlFromString(vrml);
  }
  catch(e) { ; }
};

ABNetApp.Scene.unloadAV = function(uniqID) {
    var avFldName="__av"+uniqID;
    ABNetApp.Scene.setFieldValue(avFldName,'unload',0);
};

// -- setupMyAvatar - load master avatar --

ABNetApp.Scene.setupMyAvatar = function() {
    var avFlds='__av'+ABNetApp.User.me.uniqID;
    var avatarGestureList=ABNetApp.Scene.getFieldValue(avFlds,'gestureNames_changed');

    // try and get parse the gesture list from the avatar.
    // the drop down list comes from avatar gesture list 
    if ( avatarGestureList ) {
	var theList = avatarGestureList.slice(1,-1);
	var gestureArray = theList.split(',');
	for(var i=0; i < gestureArray.length; i++ ) {
	    var tmp=gestureArray[i].replace(/^\s+/,"");
	    gestureArray[i] = tmp;
	}
	ABNetApp.Chat.uiSetGestureList(gestureArray);
    }
};

// -- setupABNetNodes -- insert our helper nodes into the 3d scene

ABNetApp.Scene.setupABNetNodes = function(s) {
  addABNetNodes();
  ABNetApp.Scene.browser.setMyAvatarURL(unescape(ABNetApp.User.me.avatarURL));
  ABNetApp.Scene.browser.setThirdPersonView(true);
  ABNetApp.the3DURL=s;
};

function addABNetNodes() {
var vrml = '#VRML V2.0 utf8\n' +
'# ABNet interface Nodes/Scripts and Prototypes\n' +
'# Copyright (c) 2002-2007 KimballSoftware\n' +
'# Version: 18-Feb-2007.2\n' +
'\n' +
'#-- Establish Proximity Node\n' +
'#-- Limits movement changes to 3 times / second\n' +
'\n' +
'DEF ABNet_PS ProximitySensor { size 1e10 1e10 1e10 }\n' +
'DEF ABNet_T0 TimeSensor { cycleInterval .3 enabled TRUE loop TRUE}\n' +
'DEF ABNet_S1 Script {\n' +
'  eventIn SFRotation set_orientation\n' +
'  eventIn SFVec3f set_position\n' +
'  eventIn SFTime trigger\n' +
'  field SFVec3f    currP 0 1.75 0\n' +
'  field SFRotation currO 0 0 1 0\n' +
'  field SFVec3f    prevP 0 0 0\n' +
'  field SFRotation prevO 0 0 0 0\n' +
'  field MFString htmlEvent []\n' +
'  field MFString emptyMFString []\n' +
'  field SFBool bDebug FALSE\n' +
'\n' +
'  url "javascript:\n' +
'  function _dprint(v) { if ( bDebug ) { print(\'ABNet_S1::\'+v); } }\n' +
'  function trigger(value,time) {\n' +
'    if ( currO[0] != prevO[0] || currO[1] != prevO[1] || currO[2] != prevO[2] || currO[3] != prevO[3] || currO[4] != prevO[4] ) {\n' +
'      prevO = currO;\n' +
'      htmlEvent[0]=\'OnEvent(onOC,\'+currO+\')\';\n' +
'      _dprint(\' trigger html event\'+htmlEvent[0]);\n' +
'      Browser.loadURL(htmlEvent, emptyMFString);\n' +
'    }\n' +
'    if ( currP[0] != prevP[0] || currP[1] != prevP[1] || currP[2] != prevP[2] ) {\n' +
'      prevP = currP;\n' +
'      htmlEvent[0]=\'OnEvent(onPC,\'+currP+\')\';\n' +
'      _dprint(\' trigger html event\'+htmlEvent[0]);\n' +
'      Browser.loadURL(htmlEvent, emptyMFString);\n' +
'    }\n' +
'  }\n' +
'  function set_position(v,t) { currP = v;}\n' +
'  function set_orientation(v,t) { currO = v;}\n' +
'  "\n' +
'}\n' +
'\n' +
'ROUTE ABNet_PS.position_changed TO ABNet_S1.set_position\n' +
'ROUTE ABNet_PS.orientation_changed TO ABNet_S1.set_orientation\n' +
'ROUTE ABNet_T0.cycleTime TO ABNet_S1.trigger\n' +
'\n' +
'# Avatar Unload Script\n' +
'DEF ABNet_S2 Script {\n' +
'  eventIn SFString remove_avatar\n' +
'  eventIn SFNode remove_me\n' +
'  field SFBool bDebug FALSE\n' +
'\n' +
'  url "javascript:\n' +
'  function _dprint(v) { if ( bDebug ) { print(\'ABNet_S2::\'+v); } }\n' +
'\n' +
'  function remove_avatar(uniqID, ts) {\n' +
'    var theName=\'__av\'+uniqID;\n' +
'    var root=Browser.getWorld();\n' +
'    \n' +
'    var theNode=root.children.findByName(theName);\n' +
'    if ( theNode ) {\n' +
'      root.removeChildren = new MFNode(theNode);\n' +
'      _dprint(\'remove_avatar nodeName=\' + theName + \' succeeded!\');\n' +
'    }\n' +
'    else {\n' +
'      _dprint(\'remove_avatar nodeName=\' + theName + \' failed! nodeName not found\');\n' +
'    }\n' +
'  }\n' +
'\n' +
'  function remove_me(theNode, ts) {\n' +
'    var root=Browser.getWorld();\n' +
'    if ( theNode ) {\n' +
'      var theName = theNode.getName();\n' +
'      root.removeChildren = new MFNode(theNode);\n' +
'      _dprint(\'remove_me nodeName=\' + theName + \' succeeded!\');\n' +
'    }\n' +
'    else {\n' +
'      _dprint(\'remove_me nodeName failed! nodeName is null\');\n' +
'    }\n' +
'  }\n' +
'  "\n' +
'  directOutput TRUE \n' +
'}\n' +
'\n' +
'# Avatar PROTO Script\n' +
'\n' +
'PROTO ABNet_Avatar [ \n' +
'  exposedField SFVec3f translation 0 0 0 \n' +
'  exposedField SFRotation rotation 0 1 0 0 \n' +
'  exposedField MFString url []\n' +
'  eventIn SFTime unload\n' +
'  exposedField SFString uniqID ""\n' +
'  eventIn SFInt32 set_gesture\n' +
'  exposedField SFString nickname ""\n' +
'  field SFNode ABNet_S2 NULL\n' +
'  exposedField MFString gestureNames ["hi","laugh","frown","agree","flip","disagree","no","sad","bye","zen","pose","walk"]\n' +
'  field SFBool isVisible TRUE\n' +
'  eventOut SFTime loaded\n' +
'  field SFNode me NULL\n' +
'] \n' +
'{ \n' +
'  PROTO ABNet_AvatarEF [\n' +
'    exposedField SFString uniqID ""\n' +
'    exposedField SFString nickname ""\n' +
'    exposedField MFString gestureNames []\n' +
'    exposedField MFString url []\n' +
'  ]\n' +
'  { Group { } }\n' +
'  DEF EF ABNet_AvatarEF { # exposed fields for script\n' +
'    uniqID IS uniqID\n' +
'    nickname IS nickname\n' +
'    gestureNames IS gestureNames\n' +
'    url IS url\n' +
'  }\n' +
'  Group { \n' +
'    children [\n' +
'      DEF T Transform { \n' +
'        translation IS translation \n' +
'        rotation IS rotation \n' +
'      } \n' +
'      DEF T2 Transform { \n' +
'        translation IS translation \n' +
'      } \n' +
'      # avatar node\n' +
'      DEF G Switch {\n' +
'        # default avatar until we load something\n' +
'        whichChoice -1\n' +
'        choice [\n' +
'          Group { }\n' +
'          Transform { translation IS translation rotation IS rotation children Transform { translation 0 -.8 0 children Shape { geometry Cylinder { radius .25 height 1.6 } appearance Appearance { material Material { diffuseColor 0 .31 .57 emissiveColor 0 .08 .16 } } } } }\n' +
'        ]\n' +
'      } \n' +
'    ] \n' +
'  } \n' +
'  \n' +
'  DEF S3 Script { \n' +
'    directOutput TRUE \n' +
'    mustEvaluate TRUE\n' +
'    eventIn SFVec3f translation \n' +
'    eventIn SFRotation rotation \n' +
'    eventIn SFInt32 set_gesture IS set_gesture\n' +
'    eventIn SFTime unload IS unload\n' +
'    field SFBool isVisible IS isVisible\n' +
'    field SFNode _self USE S3 \n' +
'    field SFNode g USE G \n' +
'    field SFNode t USE T2 \n' +
'    field SFNode exposedFields USE EF\n' +
'    field SFNode s2 IS ABNet_S2\n' +
'    field MFString avatarURL "" \n' +
'    field SFString uniqID ""\n' +
'    field MFString htmlEvent []\n' +
'    field MFString emptyMFString []\n' +
'    eventIn MFNode loaded\n' +
'    eventOut SFRotation inverted_rotation \n' +
'    eventOut SFTime gesture1_changed\n' +
'    eventOut SFTime gesture2_changed\n' +
'    eventOut SFTime gesture3_changed\n' +
'    eventOut SFTime gesture4_changed\n' +
'    eventOut SFTime gesture5_changed\n' +
'    eventOut SFTime gesture6_changed\n' +
'    eventOut SFTime gesture7_changed\n' +
'    eventOut SFTime gesture8_changed\n' +
'    eventOut SFTime gesture9_changed\n' +
'    eventOut SFTime gesture10_changed\n' +
'    eventOut SFTime gesture11_changed\n' +
'    eventOut SFTime gesture12_changed\n' +
'    eventOut SFTime gesture13_changed\n' +
'    eventOut SFTime gesture14_changed\n' +
'    eventOut SFTime gesture15_changed\n' +
'    eventOut SFTime gesture16_changed\n' +
'    eventOut SFTime gesture17_changed\n' +
'    eventOut SFTime gesture18_changed\n' +
'    eventOut SFTime gesture19_changed\n' +
'    eventOut SFTime gesture20_changed\n' +
'    eventOut SFTime gesture21_changed\n' +
'    eventOut SFTime gesture22_changed\n' +
'    eventOut SFTime gesture23_changed\n' +
'    eventOut SFTime gesture24_changed\n' +
'    eventOut SFTime gesture25_changed\n' +
'    eventOut SFTime gesture26_changed\n' +
'    eventOut SFTime gesture27_changed\n' +
'    eventOut SFTime gesture28_changed\n' +
'    eventOut SFTime gesture29_changed\n' +
'    eventOut SFTime gesture30_changed\n' +
'    eventOut SFTime gesture31_changed\n' +
'    eventOut SFTime gesture32_changed\n' +
'    eventOut SFTime gesture33_changed\n' +
'    eventOut SFTime gesture34_changed\n' +
'    eventOut SFTime gesture35_changed\n' +
'    eventOut SFTime gesture36_changed\n' +
'    eventOut SFTime gesture37_changed\n' +
'    eventOut SFTime gesture38_changed\n' +
'    eventOut SFTime gesture39_changed\n' +
'    eventOut SFTime gesture40_changed\n' +
'    eventOut SFTime gesture41_changed\n' +
'    eventOut SFTime gesture42_changed\n' +
'    eventOut SFTime gesture43_changed\n' +
'    eventOut SFTime gesture44_changed\n' +
'    eventOut SFTime gesture45_changed\n' +
'    eventOut SFTime gesture46_changed\n' +
'    eventOut SFTime gesture47_changed\n' +
'    eventOut SFTime gesture48_changed\n' +
'    eventOut SFTime gesture49_changed\n' +
'    eventOut SFTime gesture50_changed\n' +
'    eventOut SFTime gesture51_changed\n' +
'    eventOut SFTime gesture52_changed\n' +
'    eventOut SFTime gesture53_changed\n' +
'    eventOut SFTime gesture54_changed\n' +
'    eventOut SFTime gesture55_changed\n' +
'    eventOut SFTime gesture56_changed\n' +
'    eventOut SFTime gesture57_changed\n' +
'    eventOut SFTime gesture58_changed\n' +
'    eventOut SFTime gesture59_changed\n' +
'    eventOut SFTime gesture60_changed\n' +
'    eventOut SFTime gesture61_changed\n' +
'    eventOut SFTime gesture62_changed\n' +
'    eventOut SFTime gesture63_changed\n' +
'    eventOut SFTime gesture64_changed\n' +
'    eventOut SFTime gesture65_changed\n' +
'    eventOut SFTime gesture66_changed\n' +
'    eventOut SFTime gesture67_changed\n' +
'    eventOut SFTime gesture68_changed\n' +
'    eventOut SFTime gesture69_changed\n' +
'    eventOut SFTime gesture70_changed\n' +
'    eventOut SFInt32 gesture_changed\n' +
'    eventOut SFBool start_phase1\n' +
'    eventIn SFBool run_phase1\n' +
'    eventOut MFNode start_phase2\n' +
'    eventIn MFNode run_phase2\n' +
'    eventOut SFBool start_phase3\n' +
'    eventIn SFBool run_phase3\n' +
'    eventOut SFBool start_phase4\n' +
'    eventIn SFBool run_phase4\n' +
'    eventOut SFBool start_phase5\n' +
'    eventIn SFBool run_phase5\n' +
'    eventOut SFBool start_phase6\n' +
'    eventIn SFBool run_phase6\n' +
'    eventOut SFBool start_phase7\n' +
'    eventIn SFBool run_phase7\n' +
'    field SFNode theAvatarNode NULL\n' +
'    field SFBool hasSetGesture FALSE\n' +
'    field SFBool bDebug FALSE\n' +
'    field SFNode me IS me\n' +
'\n' +
'    url "javascript: \n' +
'    function _dprint(v) { if ( bDebug ) { print(\'ABNet_Avatar::\'+v); } }\n' +
'    function initialize () { \n' +
'      start_phase1=true;\n' +
'    }\n' +
'\n' +
'    function run_phase1(v,ts) { \n' +
'      avatarURL=exposedFields.url;\n' +
'      uniqID=exposedFields.uniqID;\n' +
'      if ( isVisible ) {\n' +
'          g.whichChoice=-1;\n' +
'      }\n' +
'      _dprint(\'Avatar attempting to load \'+avatarURL+\' for uniqID=\'+uniqID); \n' +
'      Browser.createVrmlFromURL(avatarURL, _self, \'loaded\'); \n' +
'    }\n' +
'\n' +
'    function loaded (val,ts) {\n' +
'      if ( val.length == 0 ) {\n' +
'        g.whichChoice=1;\n' +
'        _dprint(\'Avatar not found uniqID=\' + uniqID);\n' +
'        htmlEvent[0]=\'OnEvent(onAvatarLoadFailed,\'+uniqID+\')\';\n' +
'      }\n' +
'      else if ( val[0].getType()==\'Avatar\' ) { \n' +
'        start_phase2=val;\n' +
'        return;\n' +
'      }\n' +
'      else {\n' +
'        g.whichChoice=1; \n' +
'        _dprint(\'Where is your Avatar Node isnt the first node\');\n' +
'        htmlEvent[0]=\'OnEvent(onAvatarLoaded,\'+uniqID+\')\';\n' +
'      }\n' +
'      _dprint(\'send html event \'+htmlEvent[0]);\n' +
'      Browser.loadURL(htmlEvent,emptyMFString);\n' +
'    }\n' +
'\n' +
'    function run_phase2(val,ts) {\n' +
'      _dprint(\'Avatar found uniqID=\' + uniqID);\n' +
'      _dprint(\'Avatar url=\'+exposedFields.url);\n' +
'      if ( isVisible ) {\n' +
'        g.whichChoice=0; \n' +
'        g.choice[0]=val[0]; \n' +
'        theAvatarNode=g.choice[0];\n' +
'      }\n' +
'      else {\n' +
'        g.whichChoice=-1; \n' +
'        Browser.myAvatarURL=exposedFields.url[0];\n' +
'        Browser.showMyAvatar(true);\n' +
'        theAvatarNode=Browser.myAvatar;\n' +
'      }\n' +
'      start_phase3=true;\n' +
'    }\n' +
'\n' +
'    function run_phase3(v,ts) {\n' +
'      theAvatarNode.nickname = exposedFields.nickname;\n' +
'      if ( exposedFields.gestureNames && exposedFields.gestureNames.length > 0 ) {\n' +
'        _dprint(\'found gestureNames\');\n' +
'        exposedFields.gestureNames = theAvatarNode.gestureNames;\n' +
'        _dprint(exposedFields.gestureNames);\n' +
'      }\n' +
'      start_phase4=true;\n' +
'    }\n' +
'\n' +
'    function run_phase4(v,ts) {\n' +
'      for(indx=1;indx<70;indx++ ) {\n' +
'        setName=\'set_gesture\'+indx;\n' +
'        getName=\'gesture\'+indx+\'_changed\';\n' +
'        if ( theAvatarNode.hasEventIn(setName)) {\n' +
'          _dprint(\'Avatar adding route \'+getName+\' TO \'+setName);\n' +
'          Browser.deleteRoute(_self, getName, theAvatarNode, setName);\n' +
'          Browser.addRoute(_self, getName, theAvatarNode, setName);\n' +
'        }\n' +
'      }\n' +
'      start_phase5=true;\n' +
'    }\n' +
'\n' +
'    function run_phase5(v,ts) {\n' +
'      if ( isVisible ) {\n' +
'        if ( theAvatarNode.hasEventIn(\'set_position\') || theAvatarNode.hasEventIn(\'position\')) {\n' +
'          _dprint(\'adding route translation TO set_position\');\n' +
'          Browser.addRoute(t,\'translation_changed\',theAvatarNode,\'set_position\');\n' +
'        }\n' +
'      }\n' +
'      start_phase6=true;\n' +
'    }\n' +
'\n' +
'    function run_phase6(v,ts) {\n' +
'      if ( isVisible ) {\n' +
'        if ( theAvatarNode.hasEventIn(\'set_rotation\') || theAvatarNode.hasEventIn(\'rotation\')) {\n' +
'          _dprint(\'route rotation TO set_rotation\');\n' +
'          Browser.addRoute(t,\'rotation_changed\',theAvatarNode,\'set_rotation\');\n' +
'        }\n' +
'      }\n' +
'      start_phase7=true;\n' +
'    }\n' +
'\n' +
'    function run_phase7(v,ts) {\n' +
'      if ( isVisible ) {\n' +
'        _dprint(\'uniqID=\'+uniqID+\', \'+t.translation+\', \'+t.rotation );\n' +
'        theAvatarNode.set_position=t.translation; \n' +
'        theAvatarNode.rotation = t.rotation;\n' +
'      }\n' +
'      htmlEvent[0]=\'OnEvent(onAvatarLoaded,\'+uniqID+\')\';\n' +
'      _dprint(\'send html event \'+htmlEvent[0]);\n' +
'      Browser.loadURL(htmlEvent,emptyMFString);\n' +
'    }\n' +
'\n' +
'    function set_gesture(nIndx,ts) {\n' +
'      _dprint(\'set_gesture(\'+nIndx+\')\');\n' +
'      if (nIndx==1)  { gesture1_changed=ts; return;}\n' +
'      if (nIndx==2)  { gesture2_changed=ts; return;}\n' +
'      if (nIndx==3)  { gesture3_changed=ts; return;}\n' +
'      if (nIndx==4)  { gesture4_changed=ts; return;}\n' +
'      if (nIndx==5)  { gesture5_changed=ts; return;}\n' +
'      if (nIndx==6)  { gesture6_changed=ts; return;}\n' +
'      if (nIndx==7)  { gesture7_changed=ts; return;}\n' +
'      if (nIndx==8)  { gesture8_changed=ts; return;}\n' +
'      if (nIndx==9)  { gesture9_changed=ts; return;}\n' +
'      if (nIndx==10) { gesture10_changed=ts; return;}\n' +
'      if (nIndx==11) { gesture11_changed=ts; return;}\n' +
'      if (nIndx==12) { gesture12_changed=ts; return;}\n' +
'      if (nIndx==13) { gesture13_changed=ts; return;}\n' +
'      if (nIndx==14) { gesture14_changed=ts; return;}\n' +
'      if (nIndx==15) { gesture15_changed=ts; return;}\n' +
'      if (nIndx==16) { gesture16_changed=ts; return;}\n' +
'      if (nIndx==17) { gesture17_changed=ts; return;}\n' +
'      if (nIndx==18) { gesture18_changed=ts; return;}\n' +
'      if (nIndx==19) { gesture19_changed=ts; return;}\n' +
'      if (nIndx==20) { gesture20_changed=ts; return;}\n' +
'      if (nIndx==21) { gesture21_changed=ts; return;}\n' +
'      if (nIndx==22) { gesture22_changed=ts; return;}\n' +
'      if (nIndx==23) { gesture23_changed=ts; return;}\n' +
'      if (nIndx==24) { gesture24_changed=ts; return;}\n' +
'      if (nIndx==25) { gesture25_changed=ts; return;}\n' +
'      if (nIndx==26) { gesture26_changed=ts; return;}\n' +
'      if (nIndx==27) { gesture27_changed=ts; return;}\n' +
'      if (nIndx==28) { gesture28_changed=ts; return;}\n' +
'      if (nIndx==29) { gesture29_changed=ts; return;}\n' +
'      if (nIndx==30) { gesture30_changed=ts; return;}\n' +
'      if (nIndx==31) { gesture31_changed=ts; return;}\n' +
'      if (nIndx==32) { gesture32_changed=ts; return;}\n' +
'      if (nIndx==33) { gesture33_changed=ts; return;}\n' +
'      if (nIndx==34) { gesture34_changed=ts; return;}\n' +
'      if (nIndx==35) { gesture35_changed=ts; return;}\n' +
'      if (nIndx==36) { gesture36_changed=ts; return;}\n' +
'      if (nIndx==37) { gesture37_changed=ts; return;}\n' +
'      if (nIndx==38) { gesture38_changed=ts; return;}\n' +
'      if (nIndx==39) { gesture39_changed=ts; return;}\n' +
'      if (nIndx==40) { gesture40_changed=ts; return;}\n' +
'      if (nIndx==41) { gesture41_changed=ts; return;}\n' +
'      if (nIndx==42) { gesture42_changed=ts; return;}\n' +
'      if (nIndx==43) { gesture43_changed=ts; return;}\n' +
'      if (nIndx==44) { gesture44_changed=ts; return;}\n' +
'      if (nIndx==45) { gesture45_changed=ts; return;}\n' +
'      if (nIndx==46) { gesture46_changed=ts; return;}\n' +
'      if (nIndx==47) { gesture47_changed=ts; return;}\n' +
'      if (nIndx==48) { gesture48_changed=ts; return;}\n' +
'      if (nIndx==49) { gesture49_changed=ts; return;}\n' +
'      if (nIndx==50) { gesture50_changed=ts; return;}\n' +
'      if (nIndx==51) { gesture51_changed=ts; return;}\n' +
'      if (nIndx==52) { gesture52_changed=ts; return;}\n' +
'      if (nIndx==53) { gesture53_changed=ts; return;}\n' +
'      if (nIndx==54) { gesture54_changed=ts; return;}\n' +
'      if (nIndx==55) { gesture55_changed=ts; return;}\n' +
'      if (nIndx==56) { gesture56_changed=ts; return;}\n' +
'      if (nIndx==57) { gesture57_changed=ts; return;}\n' +
'      if (nIndx==58) { gesture58_changed=ts; return;}\n' +
'      if (nIndx==59) { gesture59_changed=ts; return;}\n' +
'      if (nIndx==60) { gesture60_changed=ts; return;}\n' +
'      if (nIndx==61) { gesture61_changed=ts; return;}\n' +
'      if (nIndx==62) { gesture62_changed=ts; return;}\n' +
'      if (nIndx==63) { gesture63_changed=ts; return;}\n' +
'      if (nIndx==64) { gesture64_changed=ts; return;}\n' +
'      if (nIndx==65) { gesture65_changed=ts; return;}\n' +
'      if (nIndx==66) { gesture66_changed=ts; return;}\n' +
'      if (nIndx==67) { gesture67_changed=ts; return;}\n' +
'      if (nIndx==68) { gesture68_changed=ts; return;}\n' +
'      if (nIndx==69) { gesture69_changed=ts; return;}\n' +
'      if (nIndx==70) { gesture70_changed=ts; return;}\n' +
'    }\n' +
'\n' +
'    function unload(ts) { \n' +
'      _dprint (\'unloading uniqID=\' + uniqID);\n' +
'      root=Browser.getWorld();\n' +
'      node=root.children.findByName(\'__av\'+uniqID);\n' +
'      node=me;\n' +
'      if ( null == node) {\n' +
'        _dprint(\'__av\'+uniqID+\' node not found\');\n' +
'        return;\n' +
'      }\n' +
'      if ( isVisible ) {\n' +
'        g.whichChoice=-1; \n' +
'        theAvatarNode=g.choice[0];\n' +
'      }\n' +
'      else {\n' +
'        theAvatarNode=Browser.myAvatar;\n' +
'      }\n' +
'      if ( theAvatarNode.hasEventIn(\'set_position\') ) {      \n' +
'        _dprint(\'removing route translation TO set_position\');\n' +
'        Browser.deleteRoute(t,\'translation_changed\',theAvatarNode,\'set_position\'); \n' +
'      }\n' +
'      if (theAvatarNode.hasEventIn(\'set_rotation\') ) {\n' +
'        _dprint(\'removing route rotation TO set_rotation\');\n' +
'        Browser.deleteRoute(t,\'rotation_changed\',theAvatarNode,\'set_rotation\');\n' +
'      }\n' +
'      for(indx=1;indx<70;indx++ ) {\n' +
'        setName=\'set_gesture\'+indx;\n' +
'        getName=\'gesture\'+indx+\'_changed\';\n' +
'        if ( theAvatarNode.hasEventIn(setName) ) {\n' +
'          _dprint(\'removing route \'+getName+\' TO \'+setName);\n' +
'          Browser.deleteRoute(_self, getName, (theAvatarNode),setName);\n' +
'        }\n' +
'      }\n' +
'      s2.remove_me=me;\n' +
'    }\n' +
'\n' +
'    function rotation(val) { \n' +
'      // need to rotate avatar 180 degrees around y axis \n' +
'      rot=new SFRotation(0,1,0,-3.14);\n' +
'      inverted_rotation=(rot).multiply(val); \n' +
'      //inverted_rotation=val; \n' +
'    } \n' +
'    " \n' +
'  }\n' +
'  ROUTE S3.start_phase1 TO S3.run_phase1\n' +
'  ROUTE S3.start_phase2 TO S3.run_phase2\n' +
'  ROUTE S3.start_phase3 TO S3.run_phase3\n' +
'  ROUTE S3.start_phase4 TO S3.run_phase4\n' +
'  ROUTE S3.start_phase5 TO S3.run_phase5\n' +
'  ROUTE S3.start_phase6 TO S3.run_phase6\n' +
'  ROUTE S3.start_phase7 TO S3.run_phase7\n' +
'  ROUTE T.rotation TO S3.rotation \n' +
'  ROUTE S3.inverted_rotation TO T2.rotation \n' +
'}\n' +
'\n' +
'DEF ABNetSharedEvents Script {\n' +
'  directOutput TRUE\n' +
'  mustEvaluate TRUE\n' +
'  eventIn SFBool initse\n' +
'  \n' +
'  eventIn MFString onSharedEvent\n' +
'  eventIn SFString groupChat\n' +
'  \n' +
'  field SFBool hasABZ FALSE\n' +
'  field SFNode abz NULL\n' +
'  field SFNode self USE ABNetSharedEvents\n' +
'  \n' +
'  # -- shared object manipulation --\n' +
'  eventIn MFString node_add\n' +
'  eventIn MFString node_changed\n' +
'  eventIn MFString node_delete\n' +
'  eventIn MFString translate\n' +
'  eventIn MFString rotate\n' +
'  eventIn MFString scale\n' +
'  eventIn MFString set_lock\n' +
'  # -- shared object manipulation --\n' +
'  \n' +
'  field SFBool bDebug FALSE # _dprint control\n' +
'  \n' +
'  url "javascript:\n' +
'  \n' +
'  //-- private functions -- \n' +
'  \n' +
'  function _dprint(v) { if ( bDebug ) { print(\'ABNetSharedEvent::\'+v); } }\n' +
'  \n' +
'  //-- initialize shared events\n' +
'  function initialize(ts) {\n' +
'    var rootChildren=Browser.getWorld().children;\n' +
'    abz=rootChildren.findByName(\'ABNetZone\');\n' +
'    if ( abz == null ) {\n' +
'      _dprint(\'ABNetZone not found shared events disabled\');\n' +
'      hasABZ=false;\n' +
'    }\n' +
'    else {\n' +
'      _dprint(\'ABNetZone found shared events enabled\');\n' +
'      hasABZ=true;\n' +
'    }\n' +
'  }\n' +
'  //-- recv and dispatch generic shared event calls from network\n' +
'  function onSharedEvent(va,ts)   {\n' +
'    _dprint(\'recv=\'+va);\n' +
'    _dprint(\'length=\'+va.length);\n' +
'    _dprint(\'event=\'+va[0]);\n' +
'    theMsg=\'\';\n' +
'    for (var i=1; i < va.length; i++ ) {\n' +
'      if ( i > 1 ) {\n' +
'        theMsg+=\' \';\n' +
'      }\n' +
'      theMsg+=va[i];\n' +
'    }\n' +
'    events=abz.events;\n' +
'    _dprint(\'search for events abz=\'+abz+\',events=\'+events);\n' +
'    _dprint(\'events.length=\'+events.length);\n' +
'    for (var i=0; i < events.length; i++ ) {\n' +
'      e=events[i];\n' +
'      _dprint(\'events[\'+i+\']=\'+e.name+\',va[0]=\'+va[0]);\n' +
'      if ( e.name == va[0] ) {\n' +
'        _dprint(\'e.type=\'+e.type);\n' +
'        if ( e.type == \'SFTime\' ) { \n' +
'          _dprint(\'ts=\'+ts);\n' +
'          e.timeFromServer = ts;\n' +
'        }\n' +
'        else if ( e.type == \'SFBool\' ) {    \n' +
'          _dprint(\'bool=\'+va[1]);\n' +
'          e.boolFromServer=parseInt(va[1]);\n' +
'        }\n' +
'        else if ( e.type == \'SFString\' ) {\n' +
'          _dprint(\'theMsg=\'+theMsg);\n' +
'          e.stringFromServer = theMsg;\n' +
'        }\n' +
'        else if ( e.type == \'SFInt32\' ) {   \n' +
'          _dprint(\'int=\'+va[1]);\n' +
'          e.int32FromServer=parseInt(va[1]);\n' +
'        }\n' +
'        else if ( e.type == \'SFFloat\' ) {   \n' +
'          _dprint(\'float=\'+va[1]);\n' +
'          e.floatFromServer=parseFloat(va[1]);\n' +
'        }\n' +
'        else if ( e.type == \'SFVec3f\' ) {\n' +
'          _dprint(\'vec3f=\'+va[1]+\' \'+va[2]+\' \'+va[3]);\n' +
'          tmpVec3f=new SFVec3f();\n' +
'          tmpVec3f[0]=parseFloat(va[1]);\n' +
'          tmpVec3f[1]=parseFloat(va[2]);\n' +
'          tmpVec3f[2]=parseFloat(va[3]);\n' +
'          e.vec3fFromServer=tmpVec3f;\n' +
'        }\n' +
'        else if ( e.type == \'SFRotation\' ) {\n' +
'          _dprint(\'rotation=\'+va[1]+\' \'+va[2]+\' \'+va[3]+\' \'+va[4]);\n' +
'          tmpRot=new SFRotation();\n' +
'          tmpRot[0]=parseFloat(va[1]);\n' +
'          tmpRot[1]=parseFloat(va[2]);\n' +
'          tmpRot[2]=parseFloat(va[3]);\n' +
'          tmpRot[3]=parseFloat(va[4]);\n' +
'          e.rotationFromServer=tmpRot;\n' +
'        }\n' +
'        else {\n' +
'          print(\'Warning! SharedEvent ignored invalid type [\'+e.type+\']\');\n' +
'        }\n' +
'        break;\n' +
'      }\n' +
'    }\n' +
'  }\n' +
'  \n' +
'  //-- recv and dispatch any text appended to the user interface\n' +
'  function groupChat(v, ts) {\n' +
'    _dprint(\'groupChat=[\'+v+\']\');\n' +
'    abz.groupChat = new MFString(v); \n' +
'  }\n' +
'  \n' +
'  "\n' +
'}\n' +
'';
ABNetApp.Scene.browser.addVrmlFromString(vrml);
}
