/**
 * TODO: select on the to station selector
 */

function SmeWidget( config )
{
  this.position = config.position;
  this.type = config.type;
  this.name = config.name;
  this.path = config.path;
  this.slug = config.slug;
  
  this.located = null;
  var widget = this;
  
  /// Location Storage functions
  var storageId = 'sm_'+this.type
  
  var getLocation = function() {
    var item = Strike.storage.getItem(storageId+'_location');
    if(!item) return null;
    return JSON.parse(item);
  }
  var setLocation = function(location) {
    if(location==null)
      Strike.storage.removeItem(storageId+'_location');
    else
      Strike.storage.setItem(storageId+'_location', JSON.stringify(location));
  }
  var storage = getLocation();
  if(storage)
    this.located = storage;
  
  var getFavorites = function() {
    var str = Strike.storage.getItem(storageId+'_favorites');
    return !str ? [] : JSON.parse(str);
  }
  var saveFavorites = function(favorites) {
    return Strike.storage.setItem(storageId+'_favorites', JSON.stringify(favorites));
  }
  var addFavorite = function(fromStation, toStation) {
    var favorites = getFavorites();
    var contains = false;
    $.each(favorites, function(favorite){
      if(favorite.fromStation.id == fromStation.id && favorite.toStation.id == toStation.id)
	contains = true;
    });
    if(!contains) {
      favorites.unshift({fromStation: fromStation, toStation: toStation});
      saveFavorites(favorites);
    }
  }
  
  /// Utils functions
  var hide = function(node) {
    node.style.display = 'none';
  }
  var show = function(node) {
    node.style.display = 'block';
  }
  var params = function(map) {
    var opts = [];
    for(var m in map) 
      opts.push(encodeURIComponent(m)+'='+encodeURIComponent(map[m]));
    return opts.join('&');
  }
  
  this.init = function() {
    if (!$('#'+this.slug+"_results")) {
      var div = document.createElement("div");
      div.id = this.slug+"_results";
      $(".tabBarPages")[0].appendChild(div);
      fillTemplate(div.id, 'container_tmpl', {widget: {type: this.type, slug: this.slug+'_results'} });
    }
    if (!$('#'+this.slug+"_favorites")) {
      var div = document.createElement("div");
      div.id = this.slug+"_favorites";
      $(".tabBarPages")[0].appendChild(div);
      fillTemplate(div.id, 'container_tmpl', {widget: {type: this.type, slug: this.slug+'_favorites'} });
    }
    Strike.locate(function(coord) {
      $.ajax({
	method: 'GET',
	type: 'json',
	url: widget.path+'/station/'+coord.latitude+'/'+coord.longitude,
	success: function(data) {
	  widget.located = (data && data['id']) ? { stationId: data.id, station: data.name, town: data.town } : null;
	  setLocation(widget.located);
	}
      });
    });
    Loader.start();
    this.mainPage();
  }
  
  this.unload = function() {
    $('#' + this.slug + "_content").innerHTML = "";
  };
  
  this.mainPage = function() {
    
    var widget = this;
    fillTemplate("#" + widget.slug + "_content", widget.type + "_main_tmpl", widget);
    
    $.each($('input.folder'), function(node){
      var selector = node.getAttribute('folder-for');
      if(selector) {
	var target = $(selector);
	if(target) {
	  if(node.checked)
	    show(target);
	  else
	    hide(target);
	  $.on(node, 'change', function(e) {
	    if(node.checked)
	      show(target);
	    else
	      hide(target);
	  });
	}
      }
    });
    
    $('#sme-favoritesPage').addEventListener('click', function() {
      widget.favoritesPage();
      Strike.next('#'+widget.slug+"_favorites");
    });
    
    var scrollerSelector = "#" + widget.slug + " .scrollView";
    var scroller = $(scrollerSelector);
    if(scroller && scroller[0]) scroller = scroller[0].scroller;
    
    if(scroller)
      scroller.destroy();
  
    var WINDOW_MINUTES = 180;

    var fromStationNode = $('#sme-fromStation');
    var toStationNode = $('#sme-toStation');
    var optionsNode = $('#sme-options');
    
    var fromStationSelector = $('#fromStationAutocomplete');
    var toStationSelector = $('#toStationSelector');

    var getAcValue = function(node) {
      return node.getAttribute('value');
    }

    var loadStations = function(container, stationFromId, onSuccess) {
      $.ajax({
	method: 'GET',
	type: 'json',
	url: widget.path+'/stations'+(!stationFromId?'':'/from/'+stationFromId), 
	success: function(data){
	  var ac_data = []
	  var locatedItem = null;
	  
	  if(!stationFromId && widget.located) {
	    var located = widget.located;
	    locatedItem = {id: located.stationId, value: 'Position actuelle ('+located.town+' - '+located.station+')', visibility: true};
	    ac_data.push(locatedItem);
	  }
	  for(var d=0; d<data.length; ++d) {
	    var station = data[d];
	    ac_data.push({id: station.id, value: (station.town||'')+' - '+station.name});
	  }
	
	  if(container.getAttribute('class')=='autocomplete') {
	    var acNode = container;
	    var ac = new Autocomplete(acNode, ac_data, { 
	      scroll: true,
	      minInterval: 50, 
	      maxInterval: 100, 
	      onFocus: function(){
		setTimeout(function(){
		  $.each($('.hideUsingAutocomplete'), function(node) {
		    hide(node);
		  });
		}, 20);
	      },
	      onBlur: function(){
		$.each($('.hideUsingAutocomplete'), function(node) {
		  show(node);
		});
	      }
	    });
	    ac.onSelect = function(item) {
	      var e = document.createEvent('HTMLEvents');
	      e.initEvent('change', false, false);
	      acNode.dispatchEvent(e);
	    }
	    if(locatedItem)
	      ac.select(locatedItem);
	  }
	  else {
	    var select = container;
	    $.each($('optgroup', select), function(node){
	      select.removeChild(node);
	    });
	    
	    var options = {};
	    for(var d=0; d<data.length; ++d) {
	      var station = data[d];
	      if(station.town) {
		var arr = options[station.town];
		if(!arr) arr = [];
		arr.push(station);
		options[station.town] = arr; 
	      }
	    }
	    
	    for(var town in options) {
	      var optgroup = document.createElement('optgroup');
	      optgroup.setAttribute('label', town);
	      $.each(options[town], function(station) {
		var option = document.createElement('option');
		option.setAttribute('value', station.id);
		option.innerHTML = station.name;
		optgroup.appendChild(option);
	      });
	      select.appendChild(optgroup);
	    }
	    
	  }
	
	  if(onSuccess) onSuccess();
	}
      });
    }

    // set the display to a specific step (by hidding/showing steps)
    // @arg lvl : 0 to 3
    var steps = [fromStationNode, toStationNode, $('#sme-lastStep') ];
    var step = function(lvl) {
      var tab = steps.slice(lvl);
      $.each(tab, function(t) {
	hide(t)
      });
      tab = steps.slice(0, lvl);
      $.each(tab, function(t) {
	show(t)
      });
    }
    
    // bind events
    
    fromStationSelector.addEventListener('change', function(){
      step(1);
      if(fromStationSelector.value) {
	loadStations(toStationSelector, fromStationSelector.value, function(){
	  step(2);
	});
      }
    }, false);
    
    toStationSelector.addEventListener('change', function(){
      if(toStationSelector.value)
	step(3);
    }, false);
    
    $.on($('.sme-action.cancel', fromStationNode), 'click', function(){
      fromStationSelector.autocompleteInstance.select(null);
      step(1);
      $('input', fromStationSelector)[0].focus();
    });
    
    var resultsPage = function() {
      step(3);
      if($('#enableOptions').checked) {
	widget.resultsPage(fromStationSelector.value, toStationSelector.value, {
	  date: $("#option-date").value, 
	  hours: $("#option-hours").value,
	  minutes: $("#option-minutes").value
	});
      }
      else
	widget.resultsPage(fromStationSelector.value, toStationSelector.value);
      Strike.next('#'+widget.slug+"_results");
    };
    
    $('#sme-search').addEventListener('click', function() {
      if(fromStationSelector.value && toStationSelector.value)
	resultsPage();
    });
    
    step(0);
    loadStations(fromStationSelector, null, function(){
      if(fromStationSelector.value) {
	loadStations(toStationSelector, fromStationSelector.value, function(){
	  step(2);
	  Strike.show("#" + widget.slug);
	  Loader.stop();
	});
      }
      else {
	step(1);
	Strike.show("#" + widget.slug);
	Loader.stop();
      }
    });
  };
  
  this.resultsPage = function(stationFromId, stationToId, options) {
    var widget = this;
    Loader.start();
    fillTemplate("#" + widget.slug + "_results_content", widget.type + "_results_tmpl", widget);
    Strike.bindScrollers('#'+this.slug+"_results");
    manager.toggleBackButton(true);
    
    var now = new Date();
    var date = !options ? now.getDate()+'/'+(now.getMonth()+1)+'/'+now.getFullYear() : options.date, 
	hours = !options ? now.getHours() : options.hours, 
	minutes = !options ? now.getMinutes() : options.minutes, 
	windowHours = 1;
    
    var formatWith2digits = function(str) {
      str += '';
      if(str.length==0)
        return '00';
      else if(str.length==1)
        return '0'+str;
      return str.substring(0,2);
    };
    var getTime = function(passage) {
      return (passage.time.hours>9 ? passage.time.hours : '&nbsp;'+passage.time.hours)+':'+formatWith2digits(''+passage.time.minutes);
    };
    var timeEquals = function(a, b) {
      return a.time.minutes == b.time.minutes && a.time.hours == b.time.hours;
    }
    var indexOfHourPairs = function(array, hourPair) {
      var i;
      for(i=0; i<array.length; ++i) {
	if(timeEquals(array[i].from, hourPair.from) 
	&& timeEquals(array[i].to,   hourPair.to))
	  return i;
	}
      return -1;
    }
    
    var firstGet = true;
    var getJourneys = function(callback) {
      var hourPairs = [];
      Loader.start();
      var opts = params({ date: date, hours: hours, minutes: minutes, windowMinutes: 60*windowHours });
      $.ajax({
	method: 'GET',
	type: 'json',
	url: widget.path+'/journeys/'+stationFromId+'/'+stationToId+'?'+opts,
	success: function(data){
	  if(firstGet) {
	    firstGet = false;
	    addFavorite(data.fromStation, data.toStation);
	  }
	  if(data.journeys.length!=0) {
	    hourPairs = []
	    $.each(data.journeys, function(journey, i){
	      var from = null;
	      var to = null;
	      for(var p=0; p<journey.passages.length && !(from && to); ++p) {
		var passage = journey.passages[p];
		if(passage.stationId==stationFromId) from = passage;
		else if(from && passage.stationId==stationToId) to = passage;
	      }
	      if(from && to) {
		if(indexOfHourPairs(hourPairs, { from: from, to: to })==-1) {
		  from.timeAsText = getTime(from);
		  to.timeAsText = getTime(to);
		  hourPairs.push({ from: from, to: to });
		}
	      }
            });
            hourPairs.sort(function(a,b){
              return a.from.time.hours*60+a.from.time.minutes > b.from.time.hours*60+b.from.time.minutes;
            });
          }
	  data['hourPairs'] = hourPairs;
	  data['windowHours'] = windowHours;
	  $("#sme-results").innerHTML='';
	  fillTemplate("#sme-results", widget.type+"_journeys_tmpl", data);
	  bindResultsEvents();
	  Loader.stop();
	  if(typeof(callback)=='function') callback(data);
	}
      });
    }
    
    var bindResultsEvents = function() {
      $.once($('#sme-moreResults'), 'click', function(){
	windowHours ++;
	getJourneys();
      });
    };
    
    getJourneys();
  }

  this.favoritesPage = function() {
    Loader.start();
    var widget = this;
    
    // manager.toggleBackButton(true);
    // fake back button because, for the moment, toggleBackButton only work for one step
    var backButton = document.createElement('div');
    var backButtonContainer = $('h1')[0];
    backButton.className='back';
    backButton.innerText='retour';
    backButtonContainer.appendChild(backButton);
    $.on(backButton, 'click', function(){
      backButtonContainer.removeChild(backButton);
      Strike.prev('#'+widget.slug+'_content');
      widget.mainPage();
    });
    show(backButton);
    
    var favorites = getFavorites();
    fillTemplate("#" + widget.slug + "_favorites", widget.type + "_favorites_tmpl", {widget: widget, favorites: favorites});
    var favoritesNode = $("#" + widget.slug + "_favorites");
    $.each($('.favorite .open', favoritesNode), function(node){
      var stationFromId = node.getAttribute('stationFromId');
      var stationToId = node.getAttribute('stationToId');
      $.on(node, 'click', function() {
	widget.resultsPage(stationFromId, stationToId);
	Strike.next('#'+widget.slug+'_results');
      })
    });
    
    $.on($('.cleanFavorites')[0], 'click', function(){
      saveFavorites([]);
      widget.favoritesPage();
    });
    
    Strike.bindScrollers('#'+widget.slug+"_favorites");
    Loader.stop();
  }
}



