// Obiekt playback, który będzie zawierał sekwencje wszystkich dźwięków
var playback = [];

// Wartości domyślne
var freestyle    = false,
    currentVoice = 'meow',
    context      = new webkitAudioContext(),
    browWidth    = $(window).width(),
    browHeight   = $(window).height(),
    source,
    sequencer;

var bar = 16,                 // 16 uderzeń na takt
    tempo = 120,              // tempo
    beat = 60 / tempo * 1000, // czas jednego uderzenia
    curBeat = 0;

// Załadowanie wszystkich dźwięków, a następnie wywołanie metody konfigurującej buty
var assets = new AbbeyLoad([voiceSet], function (buffers) {
  setupMeowShoes(buffers)
});

// Odtworzenie krótkiego dźwięku przy każdym uderzeniu, aby ułatwić użytkownikowi tupanie
function createMetronome() {
  for (i = 0; i < bar; i++) {
    playback.push({position: i, sensor: 'm'});
  }
}

// Odtworzenie dźwięku
function playSound(buffer, time) {
  source = context.createBufferSource();
  source.buffer = buffer;
  source.connect(context.destination);
  source.start(time);
}

// Śmieszne obrazki pojawiające się w różnych miejscach
function playVisual(image) {
  // Utworzenie łańcucha elementów
  var picture = $('<img class="vish" src="/imgs/' + image + '"/>');
  // Dodanie obrazu do treści strony
  $('body').append(picture);

  // Umieszczenie obrazu w przypadkowym miejscu, animacja i usunięcie
  picture.css({
            'top': Math.floor((Math.random() * browHeight) + 1 ) + 'px', 
            'left': Math.floor((Math.random() * browWidth) + 1 ) + 'px' 
      })
      .animate({'opacity':1}, 500)
      .animate({'opacity':0}, 500, function() {
        picture.remove();
      });
}

function bindClicks() {
  // Przycisk zatrzymujący
  $('#stopMusic').click(function(e) {
      e.preventDefault();
      clearInterval(sequencer);
  });

  // Freestyle! Przycisk przełączający
  $('#freeStyle').click(function(e) {
      e.preventDefault();
      freestyle ? false : true;
  });

  // Zmiana głosów
  $('.changeMode').click(function(e) {
    e.preventDefault();
    // Czy trzeba to zmienić na bieżący cel?
    var newMode = e.target.id.substr(0, e.target.id.length - 4);
    currentVoice = newMode;
  });
};

// Konfiguracja butów
function setupMeowShoes(buffers) {

  // Utworzenie metronomu
  createMetronome();
  // Pętla wykonująca obieg w n milisekund, wykonująca za każdym razem zadanie.
  // Przykład najbardziej prymitywnego sekwencera.
  
  sequencer = setInterval(function() {

    playback.forEach(function(note){

      if (note.position === curBeat) {
        // Odtworzenie dźwięku
        playSound(buffers[note.sensor], 0);
        // Wyświetlenie obrazu
        playVisual(visualSet[note.sensor]);
      }

    });

    console.log(curBeat);
    // Reset uderzenia do 0
    curBeat = (curBeat === bar - 1) ? 0 : curBeat += 1;

  }, beat);

  // Konfiguracja gniazda
  socket = io('http://localhost');

  socket.on('tap', function (data) {
    // sensorNum nie jest już dokładną opisową nazwą zmiennej
    var sensorNum = data,
        sound = currentVoice + '_' + sensorNum;

    // test...
    console.log(sound);
    console.log(data);

    // Natychmiastowe odtworzenie odpowiedniego dźwięku w celu potwierdzenia dla użytkownika
    playSound(buffers[sound], 0);
    // Dodatkowo wyświetleie obrazów
    playVisual(visualSet[sound]);

    // Jeżeli to nie kolejka freestyle z dźwiękami
    if (!freestyle) {
      // umieść nutę w kolejce
      playback.push({'position': curBeat, 'sensor': sound})
    }

  }); // koniec metody socket.on

  bindClicks();

}; // koniec funkcji setupMeowShoes