// JS API

Videomark = function() {
  return new (function() {
    
    this.Event = function () {
    };
    
    // public, r/o
    this.Event.PlayerDidEnterDOM = 'PlayerDidEnterDOM';
    
    // public, r/o
    this.Event.VideoWillPlay = 'VideoWillPlay';
    
    // private, r/o
    this.Event.VideoDidStartPlaying = 'VideoDidStartPlaying';
    
    // public, r/o
    this.Event.VideoDidStopPlaying = 'VideoDidStopPlaying';
    
    // public, but private constructor
    this.Player = function(broadcastLocationId) {
      
      // private 
      this.getParameterFromURL = function(parameterName, url) {
        parameterName = parameterName.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
        var regexS = "[\\?&]"+parameterName+"=([^&#]*)";
        var regex = new RegExp(regexS);
        var results = regex.exec(url);
        if (!results) { return ""; }
        return decodeURIComponent(results[1]);
      };
      
      // public
      this.addListener = function(eventName, eventHandler) {
        if (!eventName) {
          throw("Can't register to event: "+eventName);
        }
        var handlers = this._eventHandlersForName[eventName];
        if (!handlers) {
          handlers = [];
          this._eventHandlersForName[eventName] = handlers;
        }
        handlers.push(eventHandler);
      };
      
      // public
      this.getDOMElement = function() {
        return this._flashDOMElement;
      };
      
      // private
      this.broadcastEvent = function(eventName) {
        // console.log('broadcastEvent '+eventName+ ' for BL '+this._broadcastLocationId)
        var handlers = this._eventHandlersForName[eventName];
        if (handlers) {
          var handlerCount = handlers.length;
          for (var i=0; i<handlerCount; i++) { (handlers[i])(this); }
        }
      };

      // private
      this.setFlashDOMElement = function(flashDOMElement) {
        if (this._flashDOMElement == flashDOMElement) return;
        this._flashDOMElement = flashDOMElement;
        this.broadcastEvent(Videomark.Event.PlayerDidEnterDOM);
      };
      
      // private
      this.flashDidInit = function() {
        // execute the delayed functions
        try {
          var delayedFunctionCount = this._delayedFunctions.length;
          for (var i=0; i<delayedFunctionCount; i++) { (this._delayedFunctions[i])(); }
        } catch(e) { }
        this._delayedFunctions = [];
        
        // consume _vw parameter in document URL
        if (document.location.href.match(/_vw=1/)) {
          this.performFlashFunction('debug');
        }
      }
      
      // public
      this.getDuration = function() {
        return this._duration;
      };
      
      // public
      this.getElapsedTime = function() {
        return this._elapsedTime;
      };
      
      // private
      this.setElapsedTime = function(elapsedTime) {
        this._elapsedTime = elapsedTime;
      };
      
      // private
      this.setSoundLevel = function(soundLevel) {
        this._soundLevel = soundLevel;
      };
      
      // private
      this.setShouldPlay = function(shouldPlay) {
        if (this._shouldPlay == shouldPlay) return;
        this._shouldPlay = shouldPlay;
        
        if (this._shouldPlay) {
          if (this._ignoreNextEventVideoWillPlay || this._ignoreNextEventVideoDidStartPlaying) {
            this._ignoreNextEventVideoWillPlay = false;
            this._ignoreNextEventVideoDidStartPlaying = true;
            this._ignoreNextEventVideoDidStopPlaying = false;
          } else {
            this._ignoreNextEventVideoWillPlay = false;
            this._ignoreNextEventVideoDidStartPlaying = false;
            this._ignoreNextEventVideoDidStopPlaying = false;
            this.broadcastEvent(Videomark.Event.VideoWillPlay);
          }
        }
      };
      
      // private
      this.setPlaying = function(playing) {
        if (this._playing == playing) return;
        this._playing = playing;
        
        if (this._playing) {
          if (this._ignoreNextEventVideoWillPlay || this._ignoreNextEventVideoDidStartPlaying) {
            this._ignoreNextEventVideoWillPlay = false;
            this._ignoreNextEventVideoDidStartPlaying = false;
            this._ignoreNextEventVideoDidStopPlaying = false;
          } else {
            this._ignoreNextEventVideoWillPlay = false;
            this._ignoreNextEventVideoDidStartPlaying = false;
            this._ignoreNextEventVideoDidStopPlaying = false;
            this.broadcastEvent(Videomark.Event.VideoDidStartPlaying);
          }
        } else {
          if (this._ignoreNextEventVideoDidStopPlaying) {
            this._ignoreNextEventVideoWillPlay = false;
            this._ignoreNextEventVideoDidStartPlaying = false;
            this._ignoreNextEventVideoDidStopPlaying = false;
          } else {
            this._ignoreNextEventVideoWillPlay = false;
            this._ignoreNextEventVideoDidStartPlaying = false;
            this._ignoreNextEventVideoDidStopPlaying = false;
            this.broadcastEvent(Videomark.Event.VideoDidStopPlaying);
          }
        }
      };
      
      this.setDuration = function(duration) {
        this._duration = duration;
      };
      
      // public
      this.playerWillDisappear = function() {
        this._shouldPlay = false;
        this._playing = false;
        this._shouldOverrideAutoPlay = true;
        this._elapsedTimeBeforeHalt = this._elapsedTime;
        this._soundLevelBeforeHalt = this._soundLevel;
        this.performFlashFunction('halt');
      };
      
      // public
      this.pause = function() {
        this._shouldOverrideAutoPlay = true;
        this._ignoreNextEventVideoDidStopPlaying = true;
        this.performFlashFunction('pause_video');
      };
      
      // public
      this.play = function() {
        this._shouldOverrideAutoPlay = true;
        this._ignoreNextEventVideoWillPlay = true;
        this.performFlashFunction('play_video');
      };
      
      // private
      this.flashOptions = function() {
        var xml_options = '<?xml version="1.0" encoding="UTF-8"?>\n';
        xml_options += '<player_options>\n';
        
        if (this._shouldOverrideAutoPlay) {
          xml_options += '<auto_play type="boolean">false</auto_play>';
        }
        
        // consume parameters in document URL (once)
        if (!this._didConsumeDocumentURLOptions) {
          
          // see also consumption of parameter '_vw' in setFlashDOMElement()
          
          if (!this._shouldOverrideAutoPlay) {
            if (document.location.href.match(/_vmf=1/)) {
              xml_options += '<auto_play type="boolean">true</auto_play>';
            }
          }
          
          var _vst = this.getParameterFromURL('_vst', document.location.href);
          if (_vst && !isNaN(_vst)) {
            this._elapsedTimeBeforeHalt = parseFloat(_vst);
          }
          
          var _vtu = this.getParameterFromURL('_vtu', document.location.href);
          if (_vtu && _vtu.length > 0) {
            if (_vtu == '0' || _vtu == 'false') {
              xml_options += '<video_target_url type="boolean">false</video_target_url>';
            } else {
              xml_options += '<video_target_url>'+_vtu+'</video_target_url>'; // TODO escape XML entities
            }
          }
          
          var _vtw = this.getParameterFromURL('_vtw', document.location.href);
          if (_vtw && _vtw.length > 0) {
            xml_options += '<video_target_window>'+_vtw+'</video_target_window>'; // TODO escape XML entities
          }
          
          this._didConsumeDocumentURLOptions = true;
        }
        
        xml_options += '<sound_level type="float">'+this._soundLevelBeforeHalt+'</sound_level>';
        xml_options += '<start_time type="float">'+this._elapsedTimeBeforeHalt+'</start_time>';
        
        xml_options += '</player_options>\n';
        return xml_options;
      };
      
      // private
      this.performFlashFunction = function(functionName) {
        var performFunction = (function(player, functionName) {
          return function() {
            player._flashDOMElement[functionName]();
          };
        })(this, functionName);

        try {
          if (this._flashDOMElement && this._flashDOMElement[functionName]) {
            performFunction();
            return;
          }
        } catch(e) { }
        
        this._delayedFunctions.push(performFunction);
      };

      // private
      this._broadcastLocationId = broadcastLocationId;
      this._flashDOMElement = undefined;
      this._delayedFunctions = [];
      this._elapsedTime = 0;
      this._elapsedTimeBeforeHalt = this._elapsedTime;
      this._soundLevel = 80;
      this._soundLevelBeforeHalt = this._soundLevel;
      this._didConsumeDocumentURLOptions = false;
      this._eventHandlersForName = {};
      this._shouldOverrideAutoPlay = false;
      this._playing = false;
      this._shouldPlay = false;
      this._duration = undefined;
      this._ignoreNextEventVideoWillPlay = false;
      this._ignoreNextEventVideoDidStartPlaying = false;
      this._ignoreNextEventVideoDidStopPlaying = false;
    };
    
    // private
    this._playerForBroadcastLocationId = {};
    
    // private
    this.getPlayerForBroadcastLocationId = function(broadcastLocationId) {
      var player = this._playerForBroadcastLocationId[broadcastLocationId];
      if (!player) {
        player = new this.Player(broadcastLocationId);
        this._playerForBroadcastLocationId[broadcastLocationId] = player;
      }
      return player;
    }
    
    // public
    this.getPlayer = this.getPlayerForBroadcastLocationId;
  });
}();


// AS2 External Interface

function videomark_as2_flash_player_is_running(broadcastLocationId) {
  // console.log('videomark_as2_flash_player_is_running('+broadcastLocationId+')');
  Videomark.getPlayerForBroadcastLocationId(broadcastLocationId).setFlashDOMElement(document.getElementById('videomark_player_'+broadcastLocationId));
}

function videomark_as2_flash_player_is_ready(broadcastLocationId) {
  // console.log('videomark_as2_flash_player_is_ready('+broadcastLocationId+')');
  Videomark.getPlayerForBroadcastLocationId(broadcastLocationId).flashDidInit();
}

function videomark_as2_get_player_options(broadcastLocationId) {
  // console.log('videomark_as2_get_player_options('+broadcastLocationId+')');
  return Videomark.getPlayerForBroadcastLocationId(broadcastLocationId).flashOptions();
}

function videomark_as2_set_video_time(broadcastLocationId, elapsedTime) {
  // console.log('videomark_as2_set_video_time('+broadcastLocationId+', '+elapsedTime+')');
  Videomark.getPlayerForBroadcastLocationId(broadcastLocationId).setElapsedTime(elapsedTime);
}

function videomark_as2_set_sound_level(broadcastLocationId, soundLevel) {
  // console.log('videomark_as2_set_sound_level('+broadcastLocationId+', '+soundLevel+')');
  Videomark.getPlayerForBroadcastLocationId(broadcastLocationId).setSoundLevel(soundLevel);
}

function videomark_as2_set_should_play(broadcastLocationId, shouldPlay) {
  // console.log('videomark_as2_set_should_play('+broadcastLocationId+', '+shouldPlay+')');
  Videomark.getPlayerForBroadcastLocationId(broadcastLocationId).setShouldPlay(shouldPlay == 'true');
}

function videomark_as2_set_playing(broadcastLocationId, playing) {
  // console.log('videomark_as2_set_playing('+broadcastLocationId+', '+playing+')');
  Videomark.getPlayerForBroadcastLocationId(broadcastLocationId).setPlaying(playing == 'true');
}

function videomark_as2_set_duration(broadcastLocationId, duration) {
  // console.log('videomark_as2_set_duration('+broadcastLocationId+', '+duration+')');
  Videomark.getPlayerForBroadcastLocationId(broadcastLocationId).setDuration(duration);
}

