
/**
 * KRPANO STAGE MOUSE SENSOR ---------------------------------------------------
 */

var KrpanoOnStageSensor = function(player, delay) {
  this._player = player;
  this._interval = 0;
  this._sensibility = 5;
  this._delay = delay !== undefined ? delay : 500;
};

KrpanoOnStageSensor.prototype.stop = function() {
  stopInterval(this._interval);
};

KrpanoOnStageSensor.prototype.getInfo = function(krpano) {
  return {
    mouse: {
      x: krpano.get('mouse.x'),
      y: krpano.get('mouse.y')
    },
    stage: {
      width: krpano.get('stagewidth'),
      height: krpano.get('stageheight')
    },
    area: {
      width: krpano.get('area.width'),
      height: krpano.get('area.height')
    }
  };
};

KrpanoOnStageSensor.prototype.setMouseIn = function(isIn) {
  this._mouseIn = isIn;
};

KrpanoOnStageSensor.prototype.isMouseIn = function() {
  return this._mouseIn;
};

KrpanoOnStageSensor.prototype.start = function() {
  (function(me) {
    me._interval = setInterval( function() {
      me._player.krpanoCall(function(krpano){
        var info = me.getInfo(krpano);
        var acMouse = {
          x: info.mouse.x - info.area.width/2 + info.stage.width/2,
          y: info.mouse.y //- info.area.height/2 + info.stage.height/2
        }
        var mouseInBefore = me.isMouseIn();
        me.setMouseIn((acMouse.x > me._sensibility && acMouse.x < info.stage.width - me._sensibility) &&
          (acMouse.y > me._sensibility && acMouse.y < info.stage.height - me._sensibility));

        if(!mouseInBefore && me.isMouseIn()) {
          me.sensorIn();
        } else if(mouseInBefore && !me.isMouseIn()) {
          me.sensorOut();
        }
      });
    }, me._delay);
  })(this);
};

KrpanoOnStageSensor.prototype.sensorIn = function() {
  this._player.delayQueue(50);
  this._player.krpanoCall(function(krpano) {
    krpano.call("jseventcall('notify', 'mouseoverplayer');");
  });
  this._player.delayQueue(100);
};

KrpanoOnStageSensor.prototype.sensorOut = function() {
  this._player.delayQueue(50);
  this._player.krpanoCall(function(krpano) {
    krpano.call("jseventcall('notify', 'mouseoutplayer');");
  });
  this._player.delayQueue(100);
};

/**
 * KRPANO CONTROLLER -----------------------------------------------------------
 */

var KrpanoController = function(vemEngine, vemViewport, playerClass, playerOptions) {
  s4ntc.vem.VemController.apply(this, arguments);
  this._currentPanoId = playerOptions.current.pano_id;
  this._currentPanoType = playerOptions.current.type;
};

KrpanoController.prototype = new s4ntc.vem.VemController();
KrpanoController.prototype._currentPanoId = null;
KrpanoController.prototype._currentPanoType = null;
KrpanoController.prototype._krpanoBaseDir = window.location.host;

KrpanoController.prototype.createPlayer = function() {
  var _player = s4ntc.vem.VemController.prototype.createPlayer.apply(this, arguments);
  _player.krpanoCall(function(krpano) {
    krpano.set('area.mode', 'align');
    krpano.set('area.align', 'center');
    krpano.set('area.width', '825');
  });

  this.moss = new KrpanoOnStageSensor(_player, 500);
  this.moss.start();

  var me = this;

  this._vemEngine.bindGlobalEvent('language_changed', function() {
    me.reLoadPano();
  });

  return _player;
};

KrpanoController.prototype.playerEvent = function(name, args) {
  //        console.log(arguments);
  if(typeof VEM.api[name] == 'function') {
    var f = VEM.api[name];
    f.apply(this, args);
  } else {
    s4ntc.vem.VemController.prototype.playerEvent.apply(this, arguments);
  }
};

KrpanoController.prototype.loadPano = function(pano_id, type) {
  var pano_xml_url = this._vemEngine.urlFor(type+'_xml', {
    'lang' : this._vemEngine._options.lang,
    'id' : pano_id
  });
  var params = {
    basedir: this._krpanoBaseDir,
    vem_player_name: this._player._krpanoPlayerId,
    vem_pano_id: type+'_'+pano_id
  };
  this._player.load(pano_xml_url, params);
  this._currentPanoType = type;
  this._currentPanoId = pano_id;
};

KrpanoController.prototype.reLoadPano = function() {
  this.loadPano(this._currentPanoId, this._currentPanoType);
};

KrpanoController.prototype.lookToHotspot = function(hotspot_id, fov) {
  //this._player.delayQueue(500);
  this._player.waitFor('onblenddone');
  this._player.krpanoCall(function(krpano) {
    var hs = krpano.get(['hotspot[vem_hotspot_',hotspot_id,'].vem_id'].join(''));
    if(s4ntc.tools.test.nNOU(hs)) {
      var action = ["looktohotspot('vem_hotspot_",hotspot_id,"'"];
      if(parseFloat(fov) > 0) action.push(", ",fov);
      action.push(');');
      krpano.call(action.join(''));
    } else {
      console.log(['!!! WARNING !!! --- Hotspot n° ', hotspot_id, ' doesn\' exist in this pano!'].join(''))
    }
  });
};

/**
 * MEDIA CONTROLLER ------------------------------------------------------------
 */

var MediaController = function(vemEngine, vemViewport, playerClass, playerOptions) {
  s4ntc.vem.VemController.apply(this, arguments);
  this.falseViewport._name = vemViewport._name;
  this.falseViewport._selector = vemViewport._selector;
  this.falseViewport._element = $(this.falseViewport._selector);
  this.falseViewport.playerEvent = function() {
    vemViewport.playerEvent.apply(vemViewport, arguments);
  };
  this.falseViewport._player = this.subPlayer;
  this.falseViewport._controller = this.subController;
};

MediaController.prototype = new s4ntc.vem.VemController();
MediaController.prototype.createPlayer = function() {
  var stubPlayer = (this._player = new this._playerClass(this._vemViewport, this, this._playerOptions));
  this.loadMedia(this._playerOptions.media_type, this._playerOptions.media_id);
  return this._player;
};

MediaController.prototype.currentMediaType = '';
MediaController.prototype.subController = null;
MediaController.prototype.falseViewport = {};
MediaController.prototype._krpanoBaseDir = window.location.host;
MediaController.prototype.mediaTypes = {
  'thumbnail_media' : {
    controllerClass: s4ntc.vem.VemController,
    playerClass: s4ntc.vem.VemPlayer
  },
  'full_size_photo_media' : {
    controllerClass: s4ntc.vem.VemController,
    playerClass: s4ntc.vem.VemPlayer
  },
  'krpano_view_media' : {
    controllerClass: KrpanoController,
    playerClass: s4ntc.vem.VemKrpanoPlayer
  }
};

MediaController.prototype.initPlayerOptions = function(media_type, media_id) {
  switch (media_type) {
    case 'krpano_view_media':
      return jQuery.extend(true, {}, this._playerOptions['krpano_view_media'], {
        current: {
          pano_id: media_id,
          type: 'krpano_view_media'
        },
        krpano: {
          xml_url: VEM.engine.urlFor('krpano_view_media_xml', {
            'lang' : this._vemEngine._options.lang,
            'id' : media_id
          }
          ),
          loadParams: [
          {
            name:'basedir',
            value: this._krpanoBaseDir
          },

          {
            name:'vem_player_name',
            value: s4ntc.vem.VemKrpanoPlayerHub.players.length
          },
          {
            name:'vem_pano_id',
            value: [media_type, media_id].join('_')
          }
          ]
        }
      });
      break;
    default:
      break;
  }
  return {};
};

MediaController.prototype.removeCurrentPlayer = function() {
  switch (this.currentMediaType) {
    case 'krpano_view_media':
      s4ntc.vem.VemKrpanoPlayerHub.players[this._player._krpanoPlayerId] = null;
      break;
    default:
      break;
  }
  $(this._vemViewport._selector).children().remove();
  $(this._vemViewport._selector).html('');
  this._player = null;
};

MediaController.prototype.loadMedia = function(media_type, media_id) {
  if(this.mediaTypes[media_type] !== undefined) {
    if(this.currentMediaType !== media_type) {
      // Remove current player and replace it with an appropriate one.
      this.removeCurrentPlayer();

      var playerOptions = this.initPlayerOptions(media_type, media_id);
      this.subController = new this.mediaTypes[media_type].controllerClass(this._vemEngine, this.falseViewport, this.mediaTypes[media_type].playerClass, playerOptions);
      this.falseViewport._controller = this.subController;

      this._player = this.subController.getPlayer();
      this.falseViewport._player = this._player;

      this.currentMediaType = media_type;
    } else {
      // Load in current player
      switch (this.currentMediaType) {
        case 'krpano_view_media':
          this.subController.loadPano(media_id, 'krpano_view_media');
          break;
        default:
          break;
      }
    }
  } else {
    console.log('requesting an unexpected media type');
  }
  return this.subController;
};

/**
 * DESCRIPTION CONTROLLER ------------------------------------------------------
 */

var DescriptionController = function(vemEngine, vemViewport, playerClass, playerOptions) {
  s4ntc.vem.VemController.apply(this, arguments);
  this.current_piece_id = playerOptions.current.piece_id;
};

DescriptionController.prototype = new s4ntc.vem.VemController();
DescriptionController.prototype.current_piece_id = null;

DescriptionController.prototype.createPlayer = function() {
  var player = s4ntc.vem.VemController.prototype.createPlayer.apply(this, arguments);
  var me = this;
  this._vemEngine.bindGlobalEvent('language_changed', function() {
    me.reload();
  });
  return player;
};

DescriptionController.prototype.loadDescription = function(piece_id) {
  this.current_piece_id = piece_id;
  var url = VEM.engine.urlFor('piece_description', {
    'lang' : VEM.engine._options.lang,
    'id' : piece_id
  });
  this._player.loadHtml(url);
};

DescriptionController.prototype.reload = function() {
  this.loadDescription(this.current_piece_id);
};

/**
 * SEARCH CONTROLLER -----------------------------------------------------------
 */

var SearchController = function(vemEngine, vemViewport, playerClass, playerOptions) {
  s4ntc.vem.VemController.apply(this, arguments);
  this._fts = null;
  this._tags = {};
  this._byRefKrpano = null;
  this._byRefMap = null;
};

SearchController.prototype = new s4ntc.vem.VemController();

SearchController.prototype.createPlayer = function() {
  var player = s4ntc.vem.VemController.prototype.createPlayer.apply(this, arguments);
  var me = this;
  this._vemEngine.bindGlobalEvent('language_changed', function() {
    var pano_id = me._vemEngine._viewports['vtour']._controller._currentPanoId;
    //me.inKrpanoView(pano_id);
    me.setFullTextWords();
    me.executeSearch();
  });
  return player;
};

SearchController.prototype.inKrpanoView = function(pano_id) {
  this._byRefKrpano = pano_id;
  this._byRefMap = null;
};

SearchController.prototype.inMap = function(map_id) {
  this._byRefMap = map_id;
  this._byRefKrpano = null;
};

SearchController.prototype.anyWhere = function() {
  this._byRefKrpano = null;
  this._byRefMap = null;
};

SearchController.prototype.setFullTextWords = function(words) {
  if(s4ntc.tools.test.nNUE(words)) {
    this._fts = words;
  } else {
    this._fts = null;
  }
};

SearchController.prototype.requireTag = function(short_name) {
  this._tags[short_name] = 'required';
};

SearchController.prototype.refuseTag = function(short_name) {
  this._tags[short_name] = 'refused';
};

SearchController.prototype.includeTag = function(short_name) {
  this._tags[short_name] = 'included';
};

SearchController.prototype.removeTag = function(short_name) {
  delete this._tags[short_name];
};

SearchController.prototype.resetTags = function() {
  this._tags = {};
};

SearchController.prototype.executeSearch = function() {
  var valid_search = false;
  var data = [];
  var c = {
    'required': 0,
    'refused': 0,
    'included': 0
  };
  for( var short_name in this._tags) {
    var type = this._tags[short_name];
    data.push({
      name: [type,'_tags[',c[type]++,']'].join(''),
      value: short_name
    });
    valid_search = true;
  }
  if(s4ntc.tools.test.nNUE(this._fts)) {
    data.push({
      name: 'fts',
      value: this._fts
    });
    valid_search = true;
  }

  if(s4ntc.tools.test.nNUE(this._byRefKrpano)) {
    data.push({
      name: 'in_krpano_view',
      value: this._byRefKrpano
    });
    valid_search = true;
  }
  if(s4ntc.tools.test.nNUE(this._byRefMap)) {
    data.push({
      name: 'in_map',
      value: this._byRefMap
    });
    valid_search = true;
  }

  var me = this;

  if(valid_search)
    VEM.api.searchpieces(data, function(collection) {
      me._player.drawCollection(collection);
      me._vemViewport._element.find('[data_collection_id]').each(function() {
        var $piece_element = $(this);
        var piece_element_id = $piece_element.attr('data_collection_id');
        var piece = me._player._collectionElements[piece_element_id];

        var piece_media = piece.Media != null ? eval(['(',piece.Media,')'].join('')) : {};

        if(piece_media['KRPANO'] !== undefined && piece_media['KRPANO'].length > 0) {
          $piece_element.hover(function() {
            $(this).addClass('hover');
          },
          function() {
            $(this).removeClass('hover');
          });

          (function(piece_obj, $piece_el, media_id){
            $piece_el.click(function() {
              VEM.api.navigatetomedia(
                'search',
                'search_click',
                media_id,
                true,
                piece_obj.ref_krpano_hotspot_id != null ? true : false,
                true,
                30,
                piece_obj.ref_map_hotspot_id != null ? true : false,
                0.6
                );
            });
          })(piece, $piece_element, piece_media['KRPANO'][0]);
        }
      });
    });
};
