/*
Class: History
  FairPlayer History Manager Class
*/
var History = new Class({
  
  Implements: [Events, Options],
  
  options: {
    max: 7,
    create: false,
    search: false,
    onInsert: $empty,
    onRepeat: $empty,
    onShift: $empty,
    onStore: $empty
  },
  
  initialize: function(list, options){
    this.setOptions(options);
    this.list = $(list);
    this.history = [];
    this.type = list.split('-')[0];
    
    this.create = this.options.create || function(play){
      return new Element('a', { href: play.feed_url }).adopt([
        new Element('img', { alt: play.title, src: play.image }),
        new Element('span', { text: play.title, 'class': 'line1' }),
        new Element('span', { text: play.artist, 'class': 'line2' })
      ]).addEvent('click', function(event){
        event.stop();
        Fair.loadContent('/track/' + play.track_id + '?no_framset=true');
      });
    };

    this.search = this.options.search || function(history, play){
      for (var i = 0, l = history.length; i < l; i++){
        var item = history[i];
        if (item.track_id == play.track_id && item.feed_url == play.feed_url) return item;
      }
      return false;
    };
  },
  
  play: function(play, player){
    player = player || Fair.Player;
    if (!player) return;
    
    play = play || this.history.getLast();
    player.fairplay(play.track_id, play.feed_url);
  },
  
  store: function(play, player){
    player = player || Fair.Player;
    if (!player) return;
    
    var existing = this.search(this.history, play);
    if (!existing) this.insert(play);
    else this.repeat(existing);
    this.fireEvent('onStore', existing || play);
  },
  
  insert: function(play){
    if (this.options.max && this.history.length >= this.options.max) this.shift();
    
    var entry = this.create(play).set('title', (this.type == 'track' ? 'Learn more about' : 'View') + ' this ' + this.type);
    var button = new Element('a', { href: '#', title: 'Play this ' + this.type, 'class': 'small play button', events: {
      'click': function(event){
        event.stop();
        this.play(play);
      }.bind(this)
    }}).set('tween', { duration: 200 }).fade('hide');
    
    play.element = new Element('li', { 'class': 'small' }).addEvents({
      mouseenter: function(){ button.fade('in'); },
      mouseleave: function(){ button.fade('out'); }
    }).adopt(entry, button).inject(this.list, 'top');

    this.history.push(play);
    this.fireEvent('onInsert', play);
  },
  
  repeat: function(existing){
    var index = this.history.indexOf(existing);
    this.history = this.history.concat(this.history.splice(index, 1));
    existing.element.inject(this.list, 'top');
    this.fireEvent('onRepeat', existing);
  },
  
  shift: function(){
    this.history.shift().element.destroy();
    this.fireEvent('onShift', this.list);
  }
    
});

/*
Class: Popup
	Class for creating simple popup windows
*/
var Popup = new Class({
	
	Implements: [Events, Options],
	
	options: {
		width: 220,
		height: 360,
		menubar: "no",
		toolbar: "no",
		location: "no",
		resizable: "yes",
		statusbar: "no",
		scrollbars: "no"
	},
	
	initialize: function(options){
		this.setOptions(options);
	},
	
	prepare: function(options){
		options = $merge(this.options, options);
		options.top = screen.availHeight - this.options.height;
		options.left = 0;
		
		return Hash.getKeys(options).map(function(property){
			return property + '=' + options[property];
		}).join(',');
	},
	
	open: function(url, name, options){
		this.win = window.open(url || '#', name || 'popup', this.prepare(options));
		this.fireEvent('onOpen', this.win);
		return this;
	},
	
	close: function(){
		this.fireEvent('onClose', this.win);
		this.win.close();
		return this;
	}
	
});
if (!top.Fair) top.Fair = {};
top.Fair.Fixed = window;
var Fair = top.Fair, Local = {};
Fair.Pending = {};

Local.PlayerFrame = {
  
  init: function(){
    var detach = $('detach');
    
    detach.addEvent('click', function(event){
      if (this.Popup) this.Popup.close();
      else this.popup();
      event.stop();
    }.bind(this));
    
    var share = $('share'),
        tabs = $$('#music-tabs li a'),
        panes = $$('#music-panes div.pane');

    if (share) share.addEvent('click', function(event){
      var feed = Fair.Player.current_feed(),
          match = feed && feed.match('playlist'), model, id;
      if (match){ model = 'playlist'; id = feed.parseId(); }
      else { model = 'track'; id = Fair.Player.current_track_id(); }
      if (id) Fair.Common.Overlay.show('share', '/' + model + 's/share/' + id, model);
      event.stop();
    });
    
    if (!Fair.frameset) return;
    
    new Accordion(tabs, panes, {
      display: -1,
      opacity: false,
      alwaysHide: true,
      transition: 'quad:out',
      onActive: function(tab){ tab.addClass('active'); },
      onBackground: function(tab){ tab.removeClass('active'); }
    });
    
    $$('a').addEvent('click', function(event){
      var href = this.get('href');
      if (!href.match('#') && !href.match(/personal_events/)) Fair.loadContent(this.href);
      if (!this.hasClass('home')) event.stop();
    });
    
    this.history();
  },
  
  popup: function(){
    var fairplayer = Fair.Player;
    if (!fairplayer) return;
    
    var self = this,
        current = {},
        detach = $('detach'),
        container = $('player'),
        autoplay = fairplayer.fairplaying() ? 1 : 0,
        current_feed = fairplayer.current_feed().replace('.xspf', ''),
        current_track = fairplayer.current_track_id(),
        separator = (current_feed.indexOf('?') == -1) ? '?' : '&',
        url = current_feed + separator + 'fairplayer=large&start_track=' + current_track + '&autoplay=' + autoplay;
    
    var pending = (function(){
      current = {
        feed: Fair.Player.current_feed(),
        track: Fair.Player.current_track_id(),
        playing: Fair.Player.fairplaying()
      };
      return arguments.callee;
    })();

    var sync = function(){
      if (current.feed || current.track){
        Fair.Player.fairplay(current.track || 0, current.feed || Fair.Params.feed);
        if (!current.playing) Fair.Player.fairpause();
      }
      current = {};
    };
    
    var callbacks = {
      load: function(){
        this.Fair = top.Fair;
        Fair.Player = this.$('fairplayer');
      },
      unload: function(){
        container.show();
        detach.set('text', 'detach player');
        Fair.Player = fairplayer;
        sync.delay(1000);
      },
      beforeunload: function(){
        pending();
        self.Popup = null;
      }
    };
    
    this.Popup = new Popup({
      onOpen: function(win){
        win.Fair = top.Fair;
        win.callbacks = callbacks;
        fairplayer.fairpause();
        container.hide(true);
        detach.set('text', 'reattach player');
      }
    }).open(url, 'fairplayer_popup');
  },
  
  history: function(){
    var options = {
      create: function(play){
        return new Element('a', { href: play.feed_url }).adopt([
          new Element('img', { alt: play.title, src: play.image }),
          new Element('span', { text: play.feed_title, 'class': 'line1' })
        ]).addEvent('click', function(event){
          event.stop();
          var url = play.feed_url.replace('.xspf', '');
          url += ((url.indexOf('?') != '-1') ? '&' : '?') + 'no_frameset=true';
          Fair.loadContent(url);
        });
      },
      search: function(history, play){
        for (var i = 0, l = history.length; i < l; i++){
          var item = history[i];
          if (item.feed_url == play.feed_url) return item;
        }
        return false;
      }
    };
    
    var histories = {
      chart: new History('chart-history', options),
      playlist: new History('playlist-history', options)
    };
    
    Fair.History = new History('track-history', {
      onStore: function(play){
        var match = play.feed_url.match(/playlist|chart/);
        if (match) histories[match[0]].store(play);
      }
    });
  }
  
};

window.addEvent('domready', Local.PlayerFrame.init.bind(Local.PlayerFrame));
var fairplayer_has_user_voted = function(track_id){
  return Fair.Session && Fair.Session.track_votes && Fair.Session.track_votes.contains(track_id.toInt());
};

var fairplayer_vote_clicked = function(track_id){
  Fair.Common.Votes.vote('track', track_id);
};
// New syntax for player v3
var fairplayer_track_vote_clicked = fairplayer_vote_clicked;

var fairplayer_playlist_vote_clicked = function(playlist_id){
  Fair.Common.Votes.vote('playlist', playlist_id);
};

// TODO Remove those legacy functions a few days after player v3 moves to production
var fairplayer_played_track = function(track_id){
  track_id = track_id || Fair.Player.current_track_id();
  if (track_id) new Request({ evalScripts: true, url: '/track_plays/create' }).post({ track_id: track_id });
};

var fairplayer_played_feed = function(feed_url){
  var playlist_id = feed_url.match(/playlists?\/(\d+)/);
  if (!playlist_id || !playlist_id[1]) return;
  new Request({ evalScripts: true, url: '/playlist_plays/create' }).post({ playlist_id: playlist_id[1] });
};
// End of TODO

var sync_vote_buttons = function(){
  Fair.Common.Votes.sync('track');
};

var sync_play_buttons = function(feed_url, track_id, playing){
  if (Fair.Common){
    Fair.Common.Plays.sync(feed_url, track_id, playing);
  }
};

var fairplayer_track_history = function(track_id, feed_url, title, artist, country, duration, image, feed_title){
  var player = Fair.Player, history = Fair.History;
  if (!player || !history) return;
  
  var play = {
    image: image,
    title: title,
    artist: artist,
    country: country,
    duration: duration,
    track_id: track_id,
    feed_url: feed_url,
    feed_title: feed_title
  };
  
  history.store(play, player);
};

var fairplayer3_history = function(track_info_json, tracklist_info_json){
  var player = Fair.Player, history = Fair.History;
  if (!player || !history) return;

  var track_info = JSON.decode(track_info_json, true);
  var tracklist_info = JSON.decode(tracklist_info_json, true);
  var play = {
    image: track_info.image,
    title: track_info.title,
    artist: track_info.artist,
    country: track_info.countrycode,
    duration: track_info.duration,
    track_id: track_info.identifier,
    feed_url: tracklist_info.src,
    feed_title: tracklist_info.title
  };
  
  history.store(play, player);
};
