// Version: $Rev: 16460 $, $LastChangedDate: 2010-04-23 08:52:40 +0200 (Fr, 23 Apr 2010) $
// JavaScript utility functions to abstract various browser and installation differences for o2c objects

function o2cIsInternetExplorer()
{
  if (navigator.userAgent.toLowerCase().indexOf("msie") == -1)
    return false;
  return true;
}

function o2cIsUsableOnThisBrowser()
{
  if (navigator.platform.toLowerCase().indexOf("win32") == -1)
    return false;
  return true;
}

function o2cInternalCompareVers(instVers, wantVers)
{
  for (var i = 0; i < instVers.length; i++) {
    if (wantVers[i] < instVers[i]) return false;
    if (wantVers[i] > instVers[i]) return true;
  }
  return false;
}

function o2cInternalFindPluginDescription()
{
  var numPlugins = navigator.plugins.length;

  for (var i = 0; i < numPlugins; i++) {
    var plugin = navigator.plugins[i];
    if (plugin && (plugin.name == "O2C-Player Plug-In" || plugin.name == "o2c Player plugin")) {
      return plugin.description;
    }
  }

  return null;
}

function o2cInternalHaveUniversalPlugin()
{
  var desc = o2cInternalFindPluginDescription();
  if (!desc) return false;
  var parts = desc.split(" ");
  if (parts.length > 1) {
    var last = parts.length-1;
    if (last > 0 && parts[last]=="(U)")
      return true;
  }
  return false;
}

function o2cHavePluginVersion(reqVersion)
{
  if (reqVersion == undefined || reqVersion == '')
    throw "o2cHavePluginVersion called with illegal version";
  var v = o2cInternalFindPluginDescription();
  if (!v) return false;
  var parts = v.split(" ");
  if (parts.length > 1) {
    var last = parts.length-1;
    if (last > 0 && parts[last]=="(U)")
      last--;
    if (!o2cInternalCompareVers(parts[last].split("."), reqVersion.split(".")))
      return true;
  }
  return false;
}

function o2cIinstallPlugin(reqVersion)
{
  if (o2cIsInternetExplorer()) return false;
  if (!o2cIsUsableOnThisBrowser()) return false;

  if (reqVersion == undefined || reqVersion == '')
    throw "o2cIinstallPlugin called with illegal version";

  navigator.plugins.refresh(false);

  // if we already have a recent enough plugin version, don't bother to care how we got there
  if (o2cHavePluginVersion(reqVersion))
    return true;

  // if we have a "manually" installed plugin, use that way to update too
  if (!o2cInternalHaveUniversalPlugin()) {
    if (navigator.userAgent.toLowerCase().indexOf("chrome/") != -1)
      return o2cIinstallPluginChrome();
    else if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1)
      return o2cIinstallPluginFF();
  }

  // other browser (Safari, Opera, ...) - point to manual setup page
  window.location.href = "http://www.o2c.de/download/setup.html";
  return false;
}

function o2cIinstallPluginChrome()
{
  window.location.href = "http://www.o2c.de/download/chrome/o2cplayer.crx";
  return false; // need to reload the page before initializing the plugin
}

function o2cIinstallPluginFF()
{
  var npo2c_xpi = {'O2CPlayer plugin':'http://www.o2c.de/download/plugin/o2cplayer.xpi'};
  InstallTrigger.install(npo2c_xpi);
  return false; // need to reload the page before initializing the plugin
}

// Expand a semicolon separated list of argument=value pairs,
// where value might be quoted (either ' or ", and closing quotes might be escaped by \),
// and returm a string consisting of <param name=arg value="value" /> tags.
function o2cInternalExpandParams(args)
{
  if (args == undefined || args == '') return '';
  var res = "";
  while (args.length > 0) {
    var i = args.indexOf('=');
    if (i < 0) return;
    var start = args.substring(0, i);
    start = start.replace(/^\s*/, "");
    start = start.replace(/\s*$/, "");
    res = res + " <param name=\"" + start.replace(/"/g, '\\"')  + "\"";
    args = args.substring(i+1); if (args.length==0) break;
    args = args.replace(/^\s*/, "");
    var delim = args.charAt(0);
    var value = "";
    if (delim != '"' && delim != "'") {
      i = args.indexOf(";");
      if (i < 0) {
        value = args; args = "";
      } else {
        value = args.substring(0,i);
        args = args.substring(i);
      }
    } else {
      args = args.substring(1); if (args.length==0) break;
      i = args.indexOf(delim);
      while (i > 0 && i < args.length) {
        if (i > 0 && args.charAt(i-1) != "\\") break;
        args = args.substring(0,i-1) + args.substring(i);
        i = args.indexOf(delim, i);
      }
      value = args.substring(0, i);
      args = args.substring(i+1);
      args = args.replace(/^\s*/, "");
    }
    res = res + " value=\"" + value.replace(/"/g, '\\"') + "\" />\r\n";
    if (args.length==0) break;
    if (args.charAt(0) != ";") break;
    args = args.replace(/^;\s*/, ""); if (args.length==0) break;
  }
  return res;
}

function o2cInsertObject(id, vers, width, height, params) {
  if (id == undefined || id == '')
    throw "o2cInsertObject called with illegal html id argument";
  if (vers == undefined || vers == '')
    throw "o2cInsertObject called with illegal version argument";
  if (width == undefined || width == '')
    throw "o2cInsertObject called with illegal width argument";
  if (height == undefined || height == '')
    throw "o2cInsertObject called with illegal height argument";

  o2cIinstallPlugin(vers);

  var prefix;
  if (o2cIsInternetExplorer()) {
    var versionStr = '#version=' + vers.replace(/\./g, ",");
    if (parseFloat(navigator.appVersion.replace(/^.*MSIE /, "").replace(/;.*$/, "")) < 7.0) {
      // Bug in IE6.0 (or older): the #version check in a codebase in dynamically inserted OBJECT
      // tags does not work (causes a download of the cab everytime). Work around it by just dropping
      // the version number.
      versionStr = "";
    }
    prefix = '<object classid="CLSID:B1953AD6-C50E-11d3-B020-00A0C9251384" ' +
            'codebase="http://www.o2c.de/download/o2cplayer.cab' + versionStr + '" ';
  } else {
    prefix = '<object type="application/x-o2c-object" ';
    o2cInternalGenerateEventObject(id);
  }

  document.write(prefix + "id=" + id + " width=" + width + " height=" + height + "> " +
            o2cInternalExpandParams(params) + "</object>");
  return document.getElementById(id);
}

var o2cAllPluginEvents = new Array();

function o2cRegisterEvent(id, evName, fun)
{
  if (id == undefined || id == '')
    throw "o2cRegisterEvent called with illegal html id argument";
  if (fun == undefined || fun == '')
    throw "o2cRegisterEvent called with illegal function argument";

  var args;
  switch (evName) {
  case 'Click'              : args = 'autoAnimIndex';
                              break;
  case 'SubObjectPicked'    : args = 'Index, LocalName, DBName';
                              break;
  case 'AnimationDone'      : args = '';
                              break;
  case 'AnimationStarted'   : args = 'AnimationNo, Name, autoRepeat';
                              break;
  case 'ObjectLoaded'       : args = '';
                              break;
  case 'ThumbnailDone'      : args = '';
                              break;
  case 'TextureChanged'     : args = 'SubObjectIndex, TextureIndex, NewTextureName';
                              break;
  case 'MaterialChanged'    : args = 'SubObjectIndex, MaterialIndex, LoadingFileName';
                              break;
  case 'ObjectMove'         : args = 'objOrGrpID, whichEvnt, x, y, z';
                              break;
  case 'ObjectMoving'       : args = 'objOrGrpID, xMousePos, yMousePos, zMousePos, xCenterPos, yCenterPos, zCenterPos';
                              break;
  case 'MouseReleased'      : args = 'ev';
                              break;
  case 'ClickWithKeys'      : args = 'flags, SubAnimIndex';
                              break;
  case 'MouseDown'          : args = 'objID, whichMouseButton, flags';
                              break;
  default: throw "o2cRegisterEvent called with illegal event name argument";
  }
  if (o2cIsInternetExplorer()) {
    document.write('<script for="' + id + '" event="' + evName + '(' + args + ')" Language="JavaScript">\r\n' +
                   fun + '(' + args + ');\r\n\</script\>\r\n');
  } else {
    var code = fun + '(' + args + ');';
    if (!o2cAllPluginEvents[id]) o2cAllPluginEvents[id] = new Array();
    o2cAllPluginEvents[id][evName] = code;
  }
}

function o2cInternalGenerateEventObject(id)
{
  if (!o2cAllPluginEvents[id]) return;
  document.write('\<script Language="JavaScript"\>\r\n' +
                 'function o2cEventProxy' + id + '() { }\r\n' +
                 '  o2cEventProxy' + id + '.prototype = { \r\n' +
		         '      Click : function(autoAnimIndex) { ' + o2cAllPluginEvents[id]['Click'] + ' }, \r\n' +
		         '      SubObjectPicked : function(Index, LocalName, DBName) { ' + o2cAllPluginEvents[id]['SubObjectPicked'] + '}, \r\n' +
                 '      AnimationDone : function() { ' + o2cAllPluginEvents[id]['AnimationDone'] + ' }, \r\n' +
                 '      AnimationStarted : function(AnimationNo, Name, autoRepeat) { ' + o2cAllPluginEvents[id]['AnimationStarted'] + ' }, \r\n' +
                 '      ObjectLoaded : function() { ' + o2cAllPluginEvents[id]['ObjectLoaded'] + ' }, \r\n' +
                 '      ThumbnailDone : function() { ' + o2cAllPluginEvents[id]['ThumbnailDone'] + ' }, \r\n' +
                 '      TextureChanged : function(SubObjectIndex, TextureIndex, NewTextureName) { ' + o2cAllPluginEvents[id]['TextureChanged'] + ' }, \r\n' +
                 '      MaterialChanged : function(SubObjectIndex, MaterialIndex, LoadingFileName) { ' + o2cAllPluginEvents[id]['MaterialChanged'] + ' }, \r\n' +
                 '      ObjectMove : function(objOrGrpID, whichEvnt, x, y, z) { ' + o2cAllPluginEvents[id]['ObjectMove'] + ' }, \r\n' +
                 '      ObjectMoving : function(objOrGrpID, xMousePos, yMousePos, zMousePos, xCenterPos, yCenterPos, zCenterPos) { ' + o2cAllPluginEvents[id]['ObjectMoving'] + ' }, \r\n' +
                 '      MouseReleased : function(event) { ' + o2cAllPluginEvents[id]['MouseReleased'] + ' }, \r\n' +
                 '      ClickWithKeys : function(flags, SubAnimIndex) { ' + o2cAllPluginEvents[id]['ClickWithKeys'] + ' }, \r\n' +
                 '      MouseDown : function(objID, whichMouseButton, flags) { ' + o2cAllPluginEvents[id]['MouseDown'] + ' } \r\n' +
	             '  }; \r\n' +
                 '\</script\>\r\n');
  o2cAllPluginEvents.splice(id, 1);
}

function o2cEnableAllEvents()
{
  if (o2cIsInternetExplorer()) return;
  for (var obj in o2cAllPluginEvents) {
    var player = document.getElementById(obj);
    var evObj = eval("new o2cEventProxy" + obj + ";");
    player.EventSink = evObj;
  }
  o2cAllPluginEvents = undefined;
}

