(function () {

  var lastGBP = 0.0,
    lastUSD = 0.0,
    _fasttimer, _slowTimer, myBTC = 3.49524333;
  var lows = {
      gbp: 0,
      usd: 0
    },
    highs = {
      gbp: 0,
      usd: 0
    };

  var list = [{
    title: '101B ends',
    y: 2013,
    m: 9,
    d: 24,
    add: 1001
  },
    {
      title: 'Ends',
      y: 2016,
      m: 4,
      d: 4
    }];

  MicroEvent.mixin(this);
  var self = this;

  var addDays = function (myDate, days) {
    return new Date(myDate.getTime() + days * 24 * 60 * 60 * 1000);
  };

  var getDays = function (startdate, enddate) {
    var r, s, e;
    s = startdate.getTime();
    e = enddate.getTime();
    r = (e - s) / (24 * 60 * 60 * 1000);
    return r;
  };

  var tick = function () {
    var today = new Date();
    var start101 = new Date();
    var end101;
    var endContract = new Date();
    var third = new Date();
    start101.setFullYear(2013, 9, 24);
    end101 = addDays(start101, 1001);
    endContract.setFullYear(2016, 4, 4);
    third.setFullYear(2013, 7, 25);
    $('#one').text('101B ends: ' + Math.ceil(getDays(today,
        end101)) + " days / " + Math.ceil(getDays(today,
          end101) / 7) + " weeks");
    $('#two').text('Ends: ' + Math.ceil(getDays(today,
        endContract)) + " days / " + Math.ceil(getDays(today,
          endContract) / 7) + " weeks");
    $('#three').hide();
  };

  var get_weather = function () {
    navigator.geolocation.getCurrentPosition(show_weather);
  };

  this.bind('displayWeather', function (data) {
   $('#weather').html(data.currently.summary + ' ' + data.currently.temperature + '&deg;c&nbsp;<em>' + data.daily.summary + '</em>');
  });

  var show_weather = function (position) {
    var latitude = position.coords.latitude;
    var longitude = position.coords.longitude;
    // let's show a map or do something interesting!
    $.ajax({
      type: 'GET',
      url: 'https://api.forecast.io/forecast/0657dc0d81c037cbc89ca88e383b6bbf/' + latitude.toString() + ',' + longitude.toString() + '?units=uk2',
      data: '',
      dataType: 'jsonp',
      timeout: 10000,
      context: $('body'),
      contentType: ('application/json'),
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'PUT, GET, POST, DELETE, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type'
      },
      success: function (data) {
        self.trigger('displayWeather', data);
      },
      error: function (xhr, type) {
        console.log("ajax error");
        console.log(xhr);
        console.log(type);
      }
    });
  };

  var updateBTC = function (g, u) {
    var title, total, elm = $('#btc');
    if (lastGBP !== 0) {

      elm.removeClass();
      if (g > lastGBP) {
        elm.addClass('up');
      } else if (g < lastGBP) {
        elm.addClass('down');
      }

    } else {
      lows.gbp = g;
      lows.usd = u;

      highs.gbp = g;
      highs.usd = u;
    }

    lastGBP = g;
    lastUSD = u;

    if (g < lows.gbp) lows.gbp = g;
    if (u < lows.usd) lows.usd = u;

    if (highs.gbp < g) highs.gbp = g;
    if (highs.usd < u) highs.usd = u;

    total = myBTC * g;

    title = "High: $" + parseFloat(highs.usd.toFixed(2)) + " / Low $" + parseFloat(lows.usd.toFixed(2));
    elm.html("&#36;" + parseFloat(u.toFixed(2)) + " / &pound;" + parseFloat(g.toFixed(2)) + " (&pound;" + parseFloat(total.toFixed(2)) + ")");
    elm.prop('title', title);
  };

  var updateFX = function (data) {
    var elm = $('#fx');
    elm.html("&pound;1 = &#36;" + parseFloat(data.gpbe.toFixed(2)) + " = " + parseFloat(data.sekex.toFixed(2)) + " SEK");
  };

  this.bind('updateFX', function (data) {
    $('#fx').html("&pound;1 = &#36;" + parseFloat(data.gpbe.toFixed(2)) + " = " + parseFloat(data.sekex.toFixed(2)) + " SEK");
  });


  var btcValue = function () {
    var url = '/btc';

    $.ajax({
      type: 'GET',
      url: url,
      data: '',
      dataType: 'json',

      timeout: 10000,

      //contentType: ('application/json'),
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'PUT, GET, POST, DELETE, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type'

      },
      success: function (data) {
        // console.log(data);
        var gbp = data.bpi.GBP.rate_float,
          usd = data.bpi.USD.rate_float;

        updateBTC(gbp, usd);
      },
      error: function (xhr, type) {
        console.log("ajax error");
        console.log(xhr);
        console.log(type);
      }
    });
  };

  this.bind('getBTC', function () {
    btcValue();
  });

  var getFX = function () {
    var url = '/fx';

    $.ajax({
      type: 'GET',
      url: url,
      data: '',
      dataType: 'json',

      timeout: 10000,

      //contentType: ('application/json'),
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'PUT, GET, POST, DELETE, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type'

      },
      success: function (data) {
        var gpbex = (1 / data.rates.GBP);
        var sekex = (gpbex * data.rates.SEK);
        var fxdata = {
          usd: 1,
          gbp: data.rates.GBP,
          sek: data.rates.SEK,
          gpbe: gpbex,
          sekex: sekex
        };
        self.trigger('updateFX', fxdata);
      },
      error: function (xhr, type) {
        console.log("ajax error");
        console.log(xhr);
        console.log(type);
      }
    });
  };

  this.bind('getFX', function () {
    getFX();
  });

  var getNextTrainTime = function (toStation, fromStation) {
    var url = '/getnexttraintimes?from=' + fromStation + '&to=' + toStation;
    var target = fromStation + toStation;
    $.ajax({
      type: 'GET',
      url: url,
      data: '',
      dataType: 'json',

      timeout: 10000,

      headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'PUT, GET, POST, DELETE, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type'
      },
      success: function (data) {
        updateTrain(target, data);
      },
      error: function (xhr, type) {
        console.log("ajax error");
        console.log(xhr);
        console.log(type);
      }
    });

  };

  var updateTrain = function (n, obj) {
    var elm = $('#' + n);

    var output, status;

    output = (obj.eta == "On Time") ? obj.eta : obj.sta;
    status = (obj.eta == "On Time") ? 'delayed' : 'ontime';

    elm.html(output);
    elm.removeClass('delayed').removeClass('ontime').addClass( status);
    //elm.addClass( status);
  };

  var getTrainsCB = function (results) {
    var dest$ = $('#trainResults');
    var html = new EJS({url: '/template/trains.ejs'}).render(results);

    dest$.empty();
    dest$.append(html);
    dest$.toggle();
  };

  var getTrains = function (from, to) {
    var url = '/gettrains?from=' + from + "&to=" + to;

    $.ajax({
      type: 'GET',
      url: url,
      data: '',
      dataType: 'json',

      timeout: 10000,
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'PUT, GET, POST, DELETE, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type'

      },
      success: function (data) {
        getTrainsCB(data);
      },
      error: function (xhr, type) {
        console.log("ajax error");
        console.log(xhr);
        console.log(type);
      }
    });
  };

  var formatPassword = function (data) {

    var dest$ = $('#passwordOut');
    var html = new EJS({url: '/template/password.ejs'}).render(data);
    dest$.empty();
    dest$.append(html);
    dest$.show();
  };

  var generatePassword = function (from, to) {
    var url = '/generate';

    $.ajax({
      type: 'GET',
      url: url,
      data: '',
      dataType: 'json',

      timeout: 10000,

      headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'PUT, GET, POST, DELETE, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type'

      },
      success: function (data) {
        formatPassword(data);
      },
      error: function (xhr, type) {
        console.log("ajax error");
        console.log(xhr);
        console.log(type);
      }
    });
  };

  tick();
  get_weather();
  self.trigger('getBTC');
  self.trigger('getFX');
  getNextTrainTime('dbe', 'glq');
  getNextTrainTime('glq', 'dbe');

  // start 15 minute timer

  _fastTimer = setInterval(function () {
    self.trigger('getBTC');
    getNextTrainTime('dbe', 'glq');
    getNextTrainTime('glq', 'dbe');
  }, (60000));

  _slowTimer = setInterval(function () {

    self.trigger('getFX');
    get_weather();
  }, (60000 * 15));

  $('#dbeglq').on('click', function () {
    self.trigger('getTrains', 'dbe', 'glq');
  });

  $('#glqdbe').on('click', function () {
    self.trigger('getTrains', 'glq', 'dbe');
  });

  $('#newPassword').on('click', function () {
    generatePassword();
  });

  this.bind('getTrains', function (start, end) {
    getTrains(start, end);
  });

  document.title = 'Slack';
})();

var popitout = function (url) {
  var newwindow = window.open(url, 'name', 'height=600,width=570');
  if (window.focus) {
    newwindow.focus()
  }
  return false;
};

var popitoutSmall = function (url) {
  var newwindow = window.open(url, 'name', 'height=400,width=520');
  if (window.focus) {
    newwindow.focus();
  }
  return false;
};