
function KrebsLocalVideo() {
  var __h264    = undefined;
  var __teaser  = [];

  var __running = []; // teaser wird abgespielt
  var __waiting = []; // teaser soll abgespielt werden

  var __an_image  = [];	// laufende animation für das teaser-bild
  var __an_button = []; // laufende animation für den play button

  var __no_button = []; // buttons kurzfristig ignorieren

  var __OP_BUTTON = 0.75;

  this.onLoad = function() {
    // alle normalen player intialisieren
    $$('div.video-player').each(function(n){ initPlayer(n); });

    // teaser nur in browser wo autoplay sinnvoll ist!
    if (canAutoplay()) {
      $$('div.video-teaser').each(function(n){ initTeaser(n); });
    }
  };

  // ------------------------------------------------------------------
  // ------------------------------------------------------------------
  // ------------------------------------------------------------------

  var canAutoplay = function() {
    return !(/iphone|ipad|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase()));  
  };

  var canH264 = function() {
    if (typeof(__h264) != 'undefined') return __h264;

    var node = document.createElement('video');

    if (!node.canPlayType) {
      __h264 = '';	// wert definieren, damit die funktion nicht
			// ständig neu testen muss

    } else {
      __h264 = node.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
    }

    return __h264;
  };

  var videoURL = function(_file) { 
    return 'http://'+window.location.hostname+':8080/video/'+_file;
  };

  var posterURL = function(_file) {
    return '/.krebs/video/'+_file;
  };

  // ------------------------------------------------------------------
  // ------------------------------------------------------------------
  // ------------------------------------------------------------------

  var initPlayer = function(_node) {
    var   id = _node.identify();	// id vergeben, falls fehlend
    var data = KrebsLocalBase.getMediaData('Video', id);
					// medien-daten zusammentragen
    if (!data) return;

    data.id = id + '_player';

    // nativen player einbinden, wann immer moeglich
    if (canH264()) return KrebsLocalVideo.insertH264(_node, data); 
    
    // ansonsten fallback auf flash, wenn moeglich
    if (KrebsLocalVideo.insertFlashPlayer(id, data)) return;

    // wenn flash nicht ging, bauen wir einen download link
    createDownload(_node, data);
  }

  // ------------------------------------------------------------------
  // ------------------------------------------------------------------
  // ------------------------------------------------------------------

  var initTeaser = function(_node) {
    var   id = _node.identify();
    var data = KrebsLocalBase.getMediaData('Video', id);

    if (!data) return;

    var cid = id + '_cont';
    var pid = id + '_player';
    var bid = id + '_button';

    var image = _node.select('div.video-teaser-image')[0];
    var video = new Element('div', { id : cid, 'class' : 'video-teaser-video' });

    _node.insert({ top : video});

    var button = new Element('div', { id : bid, 'class' : 'video-teaser-button' });
        button.hide();
        button.setOpacity(0);

    _node.insert(button);

    var cookie = data.cookie || id;

    __teaser[pid] = { 
      id : id, cookie : cookie, teaser : _node, 
      image : image, video : video, button : button
    };

    // autoplay aktivieren, wenn innert karenzzeit nicht gespielt
    if (KrebsLocalBase.getCookie('teaser,'+cookie)) {
      __teaser[pid].hazCookie = 1;

    }else{
      __teaser[pid].autoplay = 1;
    }

    data.id = pid;

    if (canH264() == 'probably') {
      KrebsLocalVideo.insertH264(video, data);

    }else{
      KrebsLocalVideo.insertFlashPlayer( cid, 
        { id : pid, type : 'teaser', video: data.video } );
    }
  };

  var teaserReadyH264 = function(_teaser, _player) {
    _teaser.player = _player;

    Event.observe(_player, 'playing', function(){ showTeaserPlayer(_teaser); });
    Event.observe(_player, 'ended',   function(){ teaserCompleted(_teaser); });

    teaserReady(_teaser);
  };

  this.teaserReadyFlash = function(_obj) { 
    var teaser = __teaser[_obj.id];

    if (!teaser) return;

    var player = window.document[_obj.id];

    if (!player) return;

    teaser.player = player;

    player.addModelListener("STATE", "KrebsLocalVideo.teaserStateChange");

    teaserReady(teaser);
  };

  var teaserReady = function(_teaser) {
    observeTeaser(_teaser);

    if (_teaser.autoplay) teaserPlay(_teaser, 1);
  };

  var observeTeaser = function(_teaser) {
    Event.observe(_teaser.teaser, 'mouseover', function() { 
      if (__no_button[_teaser.id]) return;

      if (__running[_teaser.id]) {
        showButton(_teaser, 'stop', 1); 

      }else if(__waiting[_teaser.id]) {
        showButton(_teaser, 'wait', 1); 

      }else{
        showButton(_teaser, 'play', 1); 
      }
    });

    Event.observe(_teaser.button, 'mouseout',  function() { 
      if (!__waiting[_teaser.id]) hideButton(_teaser, 1); 
    });

    Event.observe(_teaser.button, 'click',  function() { 
      if (__running[_teaser.id] || __waiting[_teaser.id]) {
        teaserStop(_teaser); 

      }else{
        showButton(_teaser, 'wait');

        teaserPlay(_teaser); 
      }
    });
  };

  var teaserPlay = function(_teaser, _auto) {
    if (__running[_teaser.id]) return;

    __waiting[_teaser.id] = 1;

    // wir starten immer von anfang an!
    if (__h264) {
      _teaser.player.currentTime = 0;
      _teaser.player.play();

    }else{
      _teaser.player.sendEvent("SEEK", 0);
      _teaser.player.sendEvent("PLAY", "true");
    }
  };

  var teaserStop = function(_teaser) {

    if (__h264) {
      _teaser.player.pause();

    }else{
      _teaser.player.sendEvent("PLAY", "false");
    }

    // als gespielt vermerken, auch wenn abgebrochen wurde
    markAsSeen(_teaser);

    // beim stop warten wir nicht auf events, sondern 
    // verstecken den teaser sofort!
    hideTeaserPlayer(_teaser);
  };

  var markAsSeen = function(_teaser) {
    if (_teaser.hazCookie) return;

    KrebsLocalBase.setCookie('teaser,'+_teaser.cookie, 1, 90);
     
    _teaser.hazCookie = 1;
  }

  this.teaserStateChange = function(_obj) {
    var _teaser = __teaser[_obj.id];
  
    if (_obj.newstate == 'PLAYING') {
      showTeaserPlayer(_teaser);

    }else if (_obj.newstate == 'COMPLETED') {
      teaserCompleted(_teaser);
    }
  };

  var teaserCompleted = function(_teaser) {
    hideTeaserPlayer(_teaser);

    if (__h264) _teaser.player.pause(); 

    markAsSeen(_teaser);
 
    _teaser.completed = 1;
  };

  var showButton = function(_teaser, _key, _slow) {
    var button = _teaser.button;
    var bclass = 'video-teaser-button-'+_key;

    if (_teaser.bclass) button.removeClassName(_teaser.bclass);
 
    button.addClassName(bclass);
    
    _teaser.bclass = bclass;

    if (button.getOpacity() == __OP_BUTTON) {
      button.show(); // just for sure
      return;
    }
  
    if (_slow) {
      var aid = _teaser.id;

      if (__an_button[aid]) __an_button[aid].stop();

      button.show();

      __an_button[aid] = KrebsLocalBaseAnimation.animate(200, { 
        from  : button.getOpacity(), to : __OP_BUTTON,
        call  : function(v) { button.setOpacity(v); },
        after : function() { __an_button[aid] = 0; }
      });

    }else{
      button.setOpacity(__OP_BUTTON);
      button.show();
    }
  };

  var hideButton = function(_teaser, _slow) {
    var button = _teaser.button;

    // schneller abgang, wenn bereits ausgeblendet
    if ((button.getOpacity() == 0)){
      button.hide();
      return;
    }

    // langsames ausblenden gewuenscht
    if (_slow) {
      // id für animation bestimmen
      var aid = _teaser.id;

      // falls gerade eine animation abläuft, wird diese gestoppt
      if (__an_button[aid]) __an_button[aid].stop();
 
      // neue animation registrieren
      __an_button[aid] = KrebsLocalBaseAnimation.animate(200, { 
        from  : button.getOpacity(), to : 0.0,
        call  : function(v) { button.setOpacity(v); },
        after : function()  { button.hide(); __an_button[aid] = 0; }
      });

    }else{
      button.hide();
      button.setOpacity(0);
    }
  };

  var showTeaserPlayer = function(_teaser) {
    __no_button[_teaser.id] = 1;

    // potentiellen play/wait button ausblenden
    hideButton(_teaser);

    // abbrechen, wenn der player bereits sichtbar ist
    if (_teaser.image.getOpacity() == 0) return;

    var tid = _teaser.id;

    if (__running[tid]) return;

    __running[tid] = 1;
    __waiting[tid] = 0; 

    if (__an_image[tid]) __an_image[tid].stop();

    __an_image[tid] = KrebsLocalBaseAnimation.animate(300, { 
      from  : _teaser.image.getOpacity(), to : 0, 
      call  : function(v) { _teaser.image.setOpacity(v); },
      after : function() { 
        _teaser.image.hide();
        __an_image[tid] = 0; 
        __no_button[tid] = 0;
      }
    });
  };

  var hideTeaserPlayer = function(_teaser) {
    __no_button[_teaser.id] = 1;

    hideButton(_teaser, 1);

    if (_teaser.image.getOpacity() == 1) return;

    _teaser.image.show();

    var tid = _teaser.id;

    if (__an_image[tid]) __an_image[tid].stop();

    __an_image[tid] = KrebsLocalBaseAnimation.animate(300, { 
      from  : _teaser.image.getOpacity(), to : 1,
      call  : function(v) { _teaser.image.setOpacity(v); },
      after : function() { 
        __running[tid] = 0; 
        __waiting[tid] = 0; 
        __an_image[tid] = 0; 
        __no_button[tid] = 0;
      } 
    });
  };

  // ------------------------------------------------------------------
  // ------------------------------------------------------------------
  // ------------------------------------------------------------------

  this.insertH264 = function(_node, _data) {
    var attr = { id : _data.id, src : videoURL(_data.video) };
    var type = _data.type ? _data.type : 'player';

    if (type == 'teaser') {
      attr.width  = 500;
      attr.heigth = 200;

    }else{
      attr.width  = _data.width;
      attr.height = _data.height;

      attr.controls = 'controls';
   
      if (_data.image) attr.poster = posterURL(_data.image);

      if (_data.autoplay) { 
        attr.autoplay = 'autoplay';
      }else{
        attr.preload  = 'none';
      }
    }

    var video = new Element('video', attr);

    if (type == 'teaser') {
      Event.observe(video, 'canplay', function(){ 
        teaserReadyH264(__teaser[_data.id], video); 
      });
    }

    if (video) return _node.update(video);

    return;
  }

  this.insertFlashPlayer = function(_id, _data) {
    if (!$(_id)) return;

    var type = _data.type ? _data.type : 'player';

    if (type == 'teaser') {
      _data.width  = 500;
      _data.height = 200;
    } 

    var so = new SWFObject('/.krebs/video/.local/jwp/player.swf', 
      _data.id, _data.width, _data.height, '9');

    if (!so) return;	// just for sure

    so.addParam('allowscriptaccess','always');
    so.addParam('wmode','opaque');

    so.addVariable('file', videoURL(_data.video));
    so.addVariable('type','lighttpd');
    so.addVariable('bufferlength','10');

    if (type == 'teaser') {
      so.addParam('allowfullscreen','false');

      so.addVariable('controlbar','none');
      so.addVariable('icons', false);

      so.addVariable('autostart','false');
      so.addVariable('playerready', 'KrebsLocalVideo.teaserReadyFlash');

    } else {
      so.addParam('allowfullscreen','true');

      so.addVariable('controlbar','over');
      so.addVariable('icons', false);

      so.addVariable('autostart', _data.autoplay ? 'true' : 'false');

      if (_data.image) so.addVariable('image', posterURL(_data.image));

      so.addVariable('backcolor','C40009');
      so.addVariable('frontcolor','FFFFFF');
      so.addVariable('lightcolor','e3e3e3');
      so.addVariable('screencolor','e3e3e3');
    }


    return so.write(_id);
  };

  var createDownload = function(_node, _data) {
    // schneller abgang, wenn bereits ein download fallback definiert
    if (!_node.empty()) return;
 
    var soup = new Element('div', { 'class' : 'video-download' } );

    soup.style.width  = _data.width  + 'px';
    soup.style.height = _data.height + 'px';

    soup.insert(new Element('img', { 'src' : posterURL(_data.image) }));
    soup.insert(new Element('div', { 'class' : 'video-download-black' }));

    // leider fehlt hier noch die unterstützung für mehrsprachigkeit. die sprache 
    // der seits koennen wir ja ohne weiteren aufwand über das lang-attribute
    // von html/body bestimmen, aber woher die strings kommen, ist momentan unklar

    var div = new Element('div', { 'class' : 'video-download-link' });
        div.update('<p>Leider kann dieses Video nicht angezeigt werden.</p>');

    var link = new Element('a', { 'href' : videoURL(_data.video) });
        link.update('direkter Download');

    div.insert(link);
    soup.insert(div);

    _node.update(soup);
  };
};

// ------------------------------------------------------------------
// ------------------------------------------------------------------
// ------------------------------------------------------------------

var KrebsLocalVideo = new KrebsLocalVideo();
Event.observe(document, "dom:loaded", function(){ KrebsLocalVideo.onLoad(); } );

