function isIE() {
  return /MSIE/.test(navigator.userAgent);
}

var ConsoleLog = {
  setup: function(use_console_log, log_div_id) {
    this.use_console_log = use_console_log || false;
    this.log_div_id = log_div_id || 'console_log';
  },
  
  toggle: function() {
    this.use_console_log = this.use_console_log ? false : true;
  },
  
  log: function(message, count) {
    if(this.use_console_log) {
      if(/MSIE|Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
        if($(this.log_div_id)) {
          new Insertion.Bottom(this.log_div_id, '<li>'+message+'</li>');
        }
      } else {
        console.log(message);
      }
    } 
  },
  
  clear: function() {
    $(this.log_div_id).update('');
  }
}

// Functions needed to debug
function checkCount(num) {
  return num <= 4 || num % 50 == 0;
}

function updateCount(num) {
  if(num >= 0) {
    num++;
  } else {
    num = 0;
  }
  return num;
}

// Wrapping the console.log allows us to keep the log messages without bombing IE
ConsoleLog.setup(false);
function console_log(message, count) {
  var current_count = (count == undefined ? 0 : count);
  if(checkCount(current_count)) {
    ConsoleLog.log(message);
  }
}

var RealPlayerInstalled = null;

var MediaController = {
  hide_flash_and_show_real: function(flash_div_id, real_div_id) {
    console_log('MediaController.hide_flash_and_show_real(): START: flash_div_id('+ flash_div_id +') : real_div_id('+ real_div_id +')');
    $(MediaController.RealPlayer.flash_player_id).hide();
    $(MediaController.RealPlayer.real_player_id).showVisibility();
    console_log('MediaController.hide_flash_and_show_real(): FINISH');
  },
  
  hide_real_and_show_flash: function(real_div_id, flash_div_id) {
    console_log('MediaController.hide_real_and_show_flash(): START: real_div_id('+ real_div_id +') : flash_div_id('+ flash_div_id +') :');
    $(MediaController.RealPlayer.real_player_id).hideVisibility();
    $(MediaController.RealPlayer.flash_player_id).show();
    console_log('MediaController.hide_real_and_show_flash(): FINISH');
  },
  
  RealPlayer: {
    render_player: function(stream, real_player_id) {
      console_log("RealPlayer.render_player('"+ stream +"','"+ real_player_id +"')");
      
      // Assign the master var with the passed in value. This shouldn't actually ever change,
      // but we might as well be making all local calls to it based on its value.
      this.real_player_object_id = real_player_id;
      var sEmbedRealImageWindow = ''
        +'<object classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" '
        +'width="320" height="240" id="' + this.real_player_object_id + '">'

        +'<param name="src" value="' + stream + '" />'
        +'<param name="controls" value="Imagewindow" />'
        +'<param name="autostart" value="false" />'
        +'<param name="console" value="one" />'
        +'<param name="nologo" value="true" />'

        +'<embed src="' + stream + '" name="' + this.real_player_object_id + '" width="320" height="240" '
        +'nojava="true" controls="ImageWindow" console="one" autostart="false" '
        +'backgroundcolor="black" nologo="true" type="audio/x-pn-realaudio" '
        +'pluginspage="http://www.real.com/products/player/index.html" autogotourl="false" />'

        +'</object>';

      if(this.isRealReady()) {
        document.write(sEmbedRealImageWindow);
      }
      console_log('RealPlayer.render_player(): setup DONE');
    },

    // real_player_id is currently not necessary, based on the required hardcode of 'document.PlayerRMP'
    setup: function(real_player_id, flash_controller_id) {
      console_log('RealPlayer.setup(): START : ('+ real_player_id+','+ flash_controller_id+')', 0);

      var result = this.isRealReady();

      this.real_player_id         = 'realMediaScreen';
      this.flash_player_id        = 'flashMediaScreen';
      this.flash_controller_id    = flash_controller_id;
      this.flash_controller       = this.movie(this.flash_controller_id);

      this.playing                = false;

      // Two intervals 
      this.buffer_interval        = null;
      this.elapsed_interval       = null;

      console_log("RealPlayer.setup(): FINISHED :");

    },

    change_real_stream: function(real_div_id, real_player_id, stream, flash_controller_id) {
      console_log('RealPlayer.change_real_stream(): START : real_div_id('+ real_div_id +') : real_player_id('+ real_player_id +') flash_controller_id('+ flash_controller_id +') stream('+ stream +')');
      console_log('RealPlayer.change_real_stream(): real_player_id.isVisible('+ $(this.real_player_id).isVisible() +')');

      if(this.isRealReady()) {
        this.checkRealVisibility('RealPlayer.change_real_stream()');

        if(document.PlayerRMP) {
          console_log('REALPLAYER.CHANGE_REAL_STREAM(): About to SetSource: ');
          document.PlayerRMP.SetSource(stream);
          console_log('REALPLAYER.CHANGE_REAL_STREAM(): Called SetSource: ');
        } else {
          console_log('RealPlayer.change_real_stream(): SetSource Not a Function: ');
        }
      }
      console_log('RealPlayer.change_real_stream(): FINISH :');
    },
    
    play: function() {
      console_log('RealPlayer.play(): START : playing:'+ this.playing);
      
      if(this.isRealReady()) {
        this.checkRealVisibility('RealPlayer.play()');
        if(typeof document.PlayerRMP.CanPlay() != 'unknown') {
          console_log('RealPlayer.play(): About to Start this.buffer_interval:  playing:'+ this.playing);

          if(!this.buffer_interval) {
            this.buffer_interval = 0;
            this.buffer_interval = setInterval('MediaController.RealPlayer.updateBufferTime()', 1500);
            console_log('RealPlayer.play(): SET_INTERVAL: this.buffer_interval:'+ this.buffer_interval +':  playing:'+ this.playing);
          } else {
            console_log('RealPlayer.play(): NOT setting interval: this.buffer_interval:'+ this.buffer_interval +':  playing:'+ this.playing);
          }
        
          console_log('RealPlayer.play(): BEFORE : document.PlayerRMP.CanPlay(): '+ document.PlayerRMP.CanPlay());
          if(document.PlayerRMP.CanPlay()) {
            document.PlayerRMP.DoPlay();
            this.updateBufferTimeCallCount = 0;
            this.onUpdateElapsedTimeCallCount = 0;
            this.playing = true;
          } else {
            console_log('RealPlayer.play(): Cannot Play: '+ document.PlayerRMP.CanPlay());
            console_log('RealPlayer.play(): CanStop(): '+ document.PlayerRMP.CanStop());
            console_log('RealPlayer.play(): CanPause(): '+ document.PlayerRMP.CanPause());
          }
          console_log('RealPlayer.play(): AFTER : document.PlayerRMP.CanPlay(): '+ document.PlayerRMP.CanPlay());
        } else {
          alert('RealPlayer.play(): CanPlay NOT a function')
          console_log('RealPlayer.play(): CanPlay NOT a function');
        }
      } else {
        $(this.flash_player_id).hide();
        $(this.real_player_id).hide();
        $('no_real_player').show();
      
      }
      console_log('RealPlayer.play(): FINISH : playing:'+ this.playing);
    },
    
    pause: function() {
      console_log('RealPlayer.pause(): START : playing:'+ this.playing);
      if(this.isRealReady() && typeof document.PlayerRMP.CanPause() != 'unknown' && document.PlayerRMP.CanPause()){
        document.PlayerRMP.DoPause();
        this.stopStreamInterval();
      } 
      console_log('RealPlayer.pause(): FINISH : playing:'+ this.playing);
    },
    
    stop: function() {
      console_log('RealPlayer.stop(): START : ('+ this.real_player_id +').isVisible('+ $(this.real_player_id).isVisible() +'): playing:'+ this.playing);
      if(this.isRealReady() && typeof document.PlayerRMP.CanStop() != 'unknown') {
        console_log('RealPlayer.stop(): document.PlayerRMP.CanStop('+ document.PlayerRMP.CanStop() +') :');
        if(document.PlayerRMP.CanStop()) {
          document.PlayerRMP.DoStop();
          console_log('RealPlayer.stop(): DoStop() :');
          this.playing = false;
          this.stopStreamInterval();
        } else {
          console_log('RealPlayer.stop(): CANNOT Stop DoStop() :');
        }
      } else {
        console_log('RealPlayer.stop(): CanStop is NOT a Function');
      }
      console_log('RealPlayer.stop(): FINISH : ('+ this.real_player_id +').isVisible('+ $(this.real_player_id).isVisible() +'): playing:'+ this.playing);
    },

    startStreamInterval: function(){
      console_log('RealPlayer.startStreamInterval(): START ');
      if(this.isRealReady()) {
        if(!this.elapsed_interval) 
          this.elapsed_interval = setInterval('MediaController.RealPlayer.updateTimeElapsed()', 400);
      }
      console_log('RealPlayer.startStreamInterval(): FINISH ');
    },

    stopStreamInterval: function() {
      console_log('RealPlayer.stopStreamInterval(): STARTING ');
      if(this.isRealReady()) {
        window.clearInterval(this.elapsed_interval);
        this.elapsed_interval = null;
        window.clearInterval(this.buffer_interval);
        this.buffer_interval = null;
      }
      console_log('RealPlayer.stopStreamInterval(): FINISH ');
    },
  
    updateTimeElapsed: function () {
      this.updateTimeElapsedCallCount = updateCount(this.updateTimeElapsedCallCount);
      console_log('RealPlayer.updateTimeElapsed('+ this.updateTimeElapsedCallCount +'): START ', this.updateTimeElapsedCallCount);
      
      if(this.isRealReady() && document.PlayerRMP && $(this.real_player_id).isVisible() && (typeof document.PlayerRMP.GetPlayState() != 'unknown')) {
        console_log('RealPlayer.updateTimeElapsed('+ this.updateTimeElapsedCallCount +'): document.PlayerRMP.GetPlayState('+ document.PlayerRMP.GetPlayState() +'): this.playing:'+ this.playing, this.updateTimeElapsedCallCount);
        var play_state = document.PlayerRMP.GetPlayState();
        switch (play_state) {
		case 0 : // stopped
			// don't break but notify Flash as well as stopping the interval
			this.stopStreamInterval();
        case 1 : // contacting server
        case 2 : // buffering
        case 6 : // loading
          this.flash_controller.broadcastMessage(play_state);
          break;
        case 3 : // playing
          //this.playing = true;
        case 5 : // seeking
          console_log('RealPlayer.updateTimeElapsed('+ this.updateTimeElapsedCallCount +'): About to call onUpdateElapsedTime', this.updateTimeElapsedCallCount);
          this.onUpdateElapsedTime();
          console_log('RealPlayer.updateTimeElapsed('+ this.updateTimeElapsedCallCount +'): CALLED onUpdateElapsedTime', this.updateTimeElapsedCallCount);
          break; 
        default : // paused etc.
          console_log('RealPlayer.updateTimeElapsed('+ this.updateTimeElapsedCallCount +'): default:  ', this.updateTimeElapsedCallCount);
        
          //if(this.playing) {
            this.stopStreamInterval();
          //}
          break; 
        }
      } else {
        // communicate back to flash that the video has stopped
        this.flash_controller.broadcastMessage(0);
      }
      console_log('RealPlayer.updateTimeElapsed('+ this.updateTimeElapsedCallCount +'): FINISH ', this.updateTimeElapsedCallCount);
    },
    
    updateBufferTime: function() {
      this.updateBufferTimeCallCount = updateCount(this.updateBufferTimeCallCount);
      console_log('RealPlayer.updateBufferTime('+ this.updateBufferTimeCallCount +'): START ',this.updateBufferTimeCallCount);

      if(this.isRealReady() && $(this.real_player_id).isVisible() && (typeof document.PlayerRMP.GetPlayState() != 'unknown')) {
        console_log('RealPlayer.updateBufferTime('+ this.updateBufferTimeCallCount +'): document.PlayerRMP.GetPlayState('+ document.PlayerRMP.GetPlayState() +')',this.updateBufferTimeCallCount);
        var play_state = document.PlayerRMP.GetPlayState();

        switch (play_state) {
          case 1 : // contacting server
          case 2 : // buffering
            console_log('RealPlayer.updateBufferTime(): BUFFERING: GetBufferingTimeElapsed('+ document.PlayerRMP.GetBufferingTimeElapsed() +')')
            console_log('RealPlayer.updateBufferTime(): BUFFERING: GetBufferingTimeRemaining('+ document.PlayerRMP.GetBufferingTimeRemaining() +')')
            if(document.PlayerRMP.GetBufferingTimeElapsed() > 1500) {
              if(this.playing) {
                this.play();
              }
            }
          case 5 : // seeking
          case 6 : // loading
            this.flash_controller.broadcastMessage(play_state);
            break; 
          default : // stopped == 0, playing == 3
            //if(this.playing) {
              this.stopStreamInterval();
            //}
            this.bufferComplete();
            break;
        }
      } else {
        window.clearInterval(this.buffer_interval);
        this.buffer_interval = null;
        console_log('RealPlayer.updateBufferTime('+ this.updateBufferTimeCallCount +'): this.buffer_interval('+ this.buffer_interval +') MediaController.RealPlayer.buffer_interval('+ MediaController.RealPlayer.buffer_interval +') NOT CALLED', this.updateBufferTimeCallCount);
      }
      console_log('RealPlayer.updateBufferTime('+ this.updateBufferTimeCallCount +'): FINISH ', this.updateBufferTimeCallCount);
    },

    // FlashController Callbacks
    onUpdateElapsedTime: function(){
      this.onUpdateElapsedTimeCallCount = updateCount(this.onUpdateElapsedTimeCallCount);
      console_log('RealPlayer.onUpdateElapsedTime('+ this.onUpdateElapsedTimeCallCount +'): START ',this.onUpdateElapsedTimeCallCount);
      if(this.isRealReady()) {
        var iLength = document.PlayerRMP.GetLength();
        var iPosition = document.PlayerRMP.GetPosition();
        this.flash_controller.onUpdateElapsedTime(iPosition, iLength);
      } else {
        this.flash_controller.onUpdateElapsedTime(0,0);
      }
      console_log('RealPlayer.onUpdateElapsedTime('+ this.onUpdateElapsedTimeCallCount +'): FINISH ',this.onUpdateElapsedTimeCallCount);
    },

    // Stops buffering and tells Flash it's ready to play
    bufferComplete: function() {
      console_log('RealPlayer.bufferComplete(): START : this.buffer_interval('+ this.buffer_interval +')');
      if(this.isRealReady()) {
        window.clearInterval(this.buffer_interval);
        this.buffer_interval = null;
      
        this.flash_controller.onBufferComplete();
        this.startStreamInterval();
      } else {
        this.flash_controller.onBufferComplete();
      }
      console_log('RealPlayer.bufferComplete(): FINISH ');
    },
    
    getVideoLength: function() {
      console_log('RealPlayer.getVideoLength(): START :');
      if(this.isRealReady()) {
        var iLength = document.PlayerRMP.GetLength();
        this.flash_contoller.setVideoLength(iLength);
      } else {
        this.flash_contoller.setVideoLength(0);
      }
      console_log('RealPlayer.getVideoLength(): FINISH :');
    },

    setStreamPosition: function(iNewPos) {
      console_log('RealPlayer.setStreamPosition(): START ');
      if(this.isRealReady()) {
        document.PlayerRMP.SetPosition(iNewPos);
        this.flash_controller.playPause(true);
      } else {
        this.flash_controller.playPause(true);
      }
      console_log('RealPlayer.setStreamPosition(): FINISH ');
    },

    // These functions are not problematic so they've been moved down here.
    setVolume: function(volume) {
      console_log('RealPlayer.setVolume(): START :');
      if(this.isRealReady()) {
        document.PlayerRMP.SetVolume(Number(volume));
      }
      console_log('RealPlayer.setVolume(): FINISH :');
    },
    
    movie: function(movie_id) {
      if(isIE()) {
        return window[movie_id];
      } else {
        return document[movie_id];
      }
    },

    // Functions to get visibility issues
    checkRealVisibility: function(caller, make_visible) {
      console_log('checkRealVisibility: START : '+ caller +': real_player_id.isVisible('+ $(this.real_player_id).isVisible() +') : flash_player_id.isVisible('+ $(this.flash_player_id).isVisible() +') : '); 
      var make_vis = make_visible || false;
      if( !$(this.real_player_id).isVisible() && make_vis) {
       console_log('checkRealVisibility: '+ caller +': About to call hide_flash_and_show_real');
       MediaController.hide_flash_and_show_real();
      }
      console_log('checkRealVisibility: FINISH : '+ caller +': real_player_id.isVisible('+ $(this.real_player_id).isVisible() +') : flash_player_id.isVisible('+ $(this.flash_player_id).isVisible() +') : '); 
    },
    
    isRealReady: function() {
      console_log('RealPlayer.isRealReady(): START : RealPlayerInstalled:'+ RealPlayerInstalled);
      if(RealPlayerInstalled == null) {
//        var result = false;
        RealPlayerInstalled = detectReal();
      }
      console_log('RealPlayer.isRealReady(): FINISH : RealPlayerInstalled:'+ RealPlayerInstalled);
      return RealPlayerInstalled;
    }
  }
}

var detectableWithVB = false;
var pluginFound = false;

function canDetectPlugins() {
  if( detectableWithVB || (navigator.plugins && navigator.plugins.length > 0) ) {
    return true;
  } else {
    return false;
  }
}

function detectReal(redirectURL, redirectIfFound) {
  pluginFound = detectPlugin('RealPlayer');
  // if not found, try to detect with VisualBasic
  if(!pluginFound && detectableWithVB) {
    pluginFound = ( detectActiveXControl('rmocx.RealPlayer G2 Control') ||
           detectActiveXControl('RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)') ||
           detectActiveXControl('RealVideo.RealVideo(tm) ActiveX Control (32-bit)'));
  } 
  return pluginFound;//redirectCheck(pluginFound, redirectURL, redirectIfFound);
}

function detectPlugin() {
  // allow for multiple checks in a single pass
  var daPlugins = detectPlugin.arguments;
  // consider pluginFound to be false until proven true
  pluginFound = false;
  // if plugins array is there and not fake
  if (navigator.plugins && navigator.plugins.length > 0) {
    var pluginsArrayLength = navigator.plugins.length;
    // for each plugin...
    for (var pluginsArrayCounter=0; pluginsArrayCounter < pluginsArrayLength; pluginsArrayCounter++ ) {
      // loop through all desired names and check each against the current plugin name
      var numFound = 0;
      for(var namesCounter=0; namesCounter < daPlugins.length; namesCounter++) {
        // if desired plugin name is found in either plugin name or description
        if( (navigator.plugins[pluginsArrayCounter].name.indexOf(daPlugins[namesCounter]) >= 0) || 
          (navigator.plugins[pluginsArrayCounter].description.indexOf(daPlugins[namesCounter]) >= 0) ) {
          // this name was found
          numFound++;
        }
      }
      // now that we have checked all the required names against this one plugin,
      // if the number we found matches the total number provided then we were successful
      if(numFound == daPlugins.length) {
        pluginFound = true;
        // if we've found the plugin, we can stop looking through at the rest of the plugins
        break;
      }
    }
  }
  return pluginFound;
} // detectPlugin


// Here we write out the VBScript block for MSIE Windows
if (isIE()) {
    document.writeln('<script language="VBscript">');

    document.writeln('\'do a one-time test for a version of VBScript that can handle this code');
    document.writeln('detectableWithVB = False');
    document.writeln('If ScriptEngineMajorVersion >= 2 then');
    document.writeln('  detectableWithVB = True');
    document.writeln('End If');

    document.writeln('\'this next function will detect most plugins');
    document.writeln('Function detectActiveXControl(activeXControlName)');
    document.writeln('  on error resume next');
    document.writeln('  detectActiveXControl = False');
    document.writeln('  If detectableWithVB Then');
    document.writeln('     detectActiveXControl = IsObject(CreateObject(activeXControlName))');
    document.writeln('  End If');
    document.writeln('End Function');

    document.writeln('\'and the following function handles QuickTime');
    document.writeln('Function detectQuickTimeActiveXControl()');
    document.writeln('  on error resume next');
    document.writeln('  detectQuickTimeActiveXControl = False');
    document.writeln('  If detectableWithVB Then');
    document.writeln('    detectQuickTimeActiveXControl = False');
    document.writeln('    hasQuickTimeChecker = false');
    document.writeln('    Set hasQuickTimeChecker = CreateObject("QuickTimeCheckObject.QuickTimeCheck.1")');
    document.writeln('    If IsObject(hasQuickTimeChecker) Then');
    document.writeln('      If hasQuickTimeChecker.IsQuickTimeAvailable(0) Then ');
    document.writeln('        detectQuickTimeActiveXControl = True');
    document.writeln('      End If');
    document.writeln('    End If');
    document.writeln('  End If');
    document.writeln('End Function');

    document.writeln('</scr' + 'ipt>');
}
