// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

var Deferred = require('vanadium/src/lib/deferred');
var raf = require('raf');

var $ = require('./util/jquery');
var defineClass = require('./util/define-class');

var AddButton = require('./components/add-button');
var DestinationSearch = require('./components/destination-search');
var MapWidget = require('./components/map-widget');
var Messages = require('./components/messages');
var Message = require('./components/message');
var Timeline = require('./components/timeline');

var Destinations = require('./destinations');
var Identity = require('./identity');
var TravelSync = require('./travelsync');

var vanadiumWrapperDefault = require('./vanadium-wrapper');

var describeDestination = require('./describe-destination');
var naming = require('./naming');
var strings = require('./strings').currentLocale;

function bindControlToDestination(control, destination) {
  function updateOrdinal() {
    handleDestinationOrdinalUpdate(control, destination);
  }

  if (destination) {
    destination.onPlaceChange.add(control.setPlace);
    destination.onSelect.add(control.select);
    destination.onDeselect.add(control.deselect);
    destination.onOrdinalChange.add(updateOrdinal);
    control.setPlace(destination.getPlace());
    /* Since these controls are 1:1 with destinations, we don't want to stay in
     * a state where the control has invalid text but the destination is still
     * valid; that would be confusing to the user (e.g. abandoned query string
     * "restaurants" for destination 4 Privet Drive.) */
    control.onPlaceChange.add(destination.setPlace);
  }

  updateOrdinal();

  if (destination && destination.isSelected()) {
    control.select();
  } else {
    control.deselect();
  }

  return destination? function unbind() {
    destination.onPlaceChange.remove(control.setPlace);
    destination.onSelect.remove(control.select);
    destination.onDeselect.remove(control.deselect);
    destination.onOrdinalChange.remove(updateOrdinal);
    control.onPlaceChange.remove(destination.setPlace);
  } : $.noop;
}

function buildStatusErrorStringMap(statusClass, stringGroup) {
  var dict = {};
  $.each(statusClass, function(name, value) {
    dict[value] = stringGroup[name];
  });
  return dict;
}

function handleDestinationOrdinalUpdate(control, destination) {
  control.setPlaceholder(describeDestination.descriptionOpenEnded(destination));
}

var CMD_REGEX = /\/(\S*)(?:\s+(.*))?/;

var Travel = defineClass({
  publics: {
    error: function (err) {
      this.messages.push(Message.error(err));
    },

    info: function (info, promise) {
      this.messages.push(new Message({
        type: Message.INFO,
        text: info,
        promise: promise
      }));
    },

    invite: function(recipient) {
      var self = this;

      this.info(strings.sendingInvite(recipient),
        this.sync.invitationManager.invite(recipient,
            this.sync.getActiveTripOwner(), this.sync.getActiveTripId())
          .then(function() {
            var me = self.sync.invitationManager.getUsername();
            self.sync.message({
              type: Message.INFO,
              text: strings.invitationSent(recipient, me)
            });
          }, function(err) {
            if (err.id === 'v.io/v23/verror.NoServers') {
              throw strings.notReachable(recipient);
            } else {
              throw err;
            }
          }));
    }
  },

  privates: {
    handleDestinationAdd: function(destination) {
      var map = this.map;

      var control = this.timeline.add(destination.getIndex());
      bindControlToDestination(control, destination);

      control.setSearchBounds(map.getBounds());
      map.onBoundsChange.add(control.setSearchBounds);

      control.onFocus.add(function() {
        if (!destination.isSelected()) {
          map.closeActiveInfoWindow();
          destination.select();
        }
      });

      control.onSearch.add(function(results) {
        /* There seems to be a bug where if you click a search suggestion (for
         * a query, not a resolved location) in autocomplete, the input box
         * under it gets clicked and focused... I haven't been able to figure
         * out why. */
        control.focus();

        map.showSearchResults(results);
      });

      if (!destination.hasNext()) {
        this.timeline.disableAdd();
        var oldLast = this.timeline.get(-2);
        if (oldLast) {
          this.unbindLastDestinationSearchEvents(oldLast);
        }
        this.bindLastDestinationSearchEvents(control);
      }

      this.bindMiniFeedback(destination);

      return {
        destination: destination,
        control: control
      };
    },

    handleDestinationRemove: function(destination) {
      var index = destination.getIndex();
      this.unbindLastDestinationSearchEvents(this.timeline.remove(index));

      if (index >= this.destinations.count()) {
        var lastControl = this.timeline.get(-1);
        if (lastControl) {
          this.bindLastDestinationSearchEvents(lastControl);
          this.handleLastPlaceChange(lastControl.getPlace());
        }
      }
      //TODO(rosswang): reselect?
    },

    handleTimelineDestinationAdd: function() {
      this.destinations.add();
      this.timeline.get(-1).focus();
    },

    handleMiniDestinationAdd: function() {
      this.miniDestinationSearch.clear();
      this.map.closeActiveInfoWindow();

      var selectedDest = this.map.getSelectedDestination();
      var index = selectedDest?
        selectedDest.getIndex() + 1 : this.destinations.count();

      var destination = this.destinations.get(index);
      if (!destination || destination.hasPlace()) {
        destination = this.destinations.add(index);
      }

      destination.select();
      this.miniDestinationSearch.focus();
      this.miniDestinationSearch.setPlaceholder(
        destination.hasNext()?
          /* Actually, the terminal case where descriptionOpenEnded would differ
           * from description is always handled by the latter branch, but
           * semantically we would want the open-ended description here. */
          strings.add(describeDestination.descriptionOpenEnded(destination)) :
          strings['Add destination']);
    },

    bindMiniFeedback: function(destination) {
      var mf = this.miniFeedback;

      destination.onSelect.add(mf.handleSelect);
      destination.onDeselect.add(mf.handleDeselect);
    },

    initMiniFeedback: function() {
      var self = this;

      var selectedDestination;

      //context: destination
      function handlePlaceChange(place) {
        self.miniDestinationSearch.setPlace(place);
        self.miniDestinationSearch.setPlaceholder(
          strings.change(describeDestination.description(this)));
      }

      //context: destination
      function handleSelect() {
        selectedDestination = this;
        handlePlaceChange.call(this, this.getPlace());
        this.onPlaceChange.add(handlePlaceChange);
      }

      //context: destination
      function handleDeselect() {
        this.onPlaceChange.remove(handlePlaceChange);
        if (selectedDestination === this) {
          selectedDestination = null;
          if (self.miniDestinationSearch.getPlace()) {
            self.miniDestinationSearch.clear();
          }
          self.miniDestinationSearch.setPlaceholder(strings['Search']);
        }
      }

      this.miniFeedback = {
        handleSelect: handleSelect,
        handleDeselect: handleDeselect,
        handlePlaceChange: handlePlaceChange
      };
    },

    showTimeline: function() {
      if (this.$timelineContainer.hasClass('collapsed')) {
        this.$toggleTimeline.removeClass('collapsed');
        this.$timelineContainer.removeClass('collapsed');
        this.$minPanel.addClass('collapsed');
        //disable the control, but wait until offscreen to avoid distraction
        this.$minPanel.one('transitionend', this.miniDestinationSearch.disable);
        this.watchMapResizes();
      }
    },

    collapseTimeline: function() {
      if (!this.$timelineContainer.hasClass('collapsed')) {
        this.$toggleTimeline.addClass('collapsed');
        this.$timelineContainer.addClass('collapsed');
        this.$minPanel.removeClass('collapsed');
        this.miniDestinationSearch.enable();
        if (!this.miniDestinationSearch.getPlace()) {
          this.miniDestinationSearch.focus();
        }
        this.watchMapResizes();
      }
    },

    bindLastDestinationSearchEvents: function(control) {
      control.onPlaceChange.add(this.handleLastPlaceChange);
      control.onDeselect.add(this.handleLastPlaceDeselected);
    },

    unbindLastDestinationSearchEvents: function(control) {
      control.onPlaceChange.remove(this.handleLastPlaceChange);
      control.onDeselect.remove(this.handleLastPlaceDeselected);
    },

    handleLastPlaceChange: function(place) {
      if (place) {
        this.timeline.enableAdd();
      } else {
        this.timeline.disableAdd();
      }
    },

    handleLastPlaceDeselected: function() {
      /* Wait until next frame to allow selection/focus to update; we don't want
       * to remove a box that has just received focus. */
      raf(this.trimUnusedDestinations);
    },

    runCommand: function(command, rest) {
      var handler = this.commands[command];
      if (handler) {
        var args = handler.parseArgs? handler.parseArgs(rest) : [rest];
        handler.op.apply(this, args);
      } else {
        this.error('Unrecognized command ' + command);
      }
    },

    handleInvite: function(invitation) {
      var self = this;
      var invitationManager = this.sync.invitationManager;

      var sender = invitation.sender;
      var owner = invitation.owner;

      var async = new Deferred();

      var message = new Message({
        type: Message.INFO,
        html: strings.invitationReceived(sender, owner),
        promise: async.promise
      });

      message.$.find('a[name=accept]').click(function() {
        invitation.accept().then(function() {
          self.sync.watchForTrip(invitation.tripId);
          return strings.invitationAccepted(sender, owner);
        }).then(async.resolve, async.reject);
        return false;
      });
      message.$.find('a[name=decline]').click(function() {
        invitationManager.decline().then(function() {
          return strings.invitationDeclined(sender, owner);
        }).then(async.resolve, async.reject);
        return false;
      });

      invitation.onDismiss.add(function() {
        async.resolve(strings.invitationDismissed(sender, owner));
      });

      this.messages.push(message);
    },

    handleUserMessage: function(message, raw) {
      var match = CMD_REGEX.exec(raw);
      if (match) {
        this.runCommand(match[1], match[2]);
      } else {
        this.sync.message(message);
      }
    },

    trimUnusedDestinations: function() {
      for (var lastControl = this.timeline.get(-1);
          !lastControl.getPlace() && !lastControl.isSelected() &&
            this.destinations.count() > 1;
          lastControl = this.timeline.get(-1)) {
        this.destinations.remove(-1);
      }
    },

    /**
     * The map widget isn't very sensitive to size updates, so we need to
     * continuously invalidate during animations.
     */
    watchMapResizes: function() {
      var newWidth = this.map.$.width();
      if (newWidth !== this.mapWidth) {
        this.widthStable = 0;

        this.mapWidth = newWidth;
        this.map.invalidateSize();
        raf(this.watchMapResizes);

      } else if (this.widthStable < 5) {
        raf(this.watchMapResizes);
        this.widthStable++;
      } else {
        this.mapWidth = null;
      }
    }
  },

  init: function (opts) {
    var self = this;

    opts = opts || {};
    var vanadiumWrapper = opts.vanadiumWrapper || vanadiumWrapperDefault;

    var destinations = this.destinations = new Destinations();
    destinations.onAdd.add(this.handleDestinationAdd);
    destinations.onRemove.add(this.handleDestinationRemove);

    var map = this.map = new MapWidget(opts);
    var maps = map.maps;
    map.bindDestinations(destinations);

    var messages = this.messages = new Messages();
    var timeline = this.timeline = new Timeline(maps);

    var error = this.error;
    var vanadiumStartup = vanadiumWrapper.init(opts.vanadium)
      .then(function(wrapper) {
        wrapper.onError.add(error);
        wrapper.onCrash.add(error);

        var identity = new Identity(wrapper.getAccountName());
        var mountNames = naming.mountNames(identity);
        messages.setUsername(identity.username);

        return {
          identity: identity,
          mountNames: mountNames,
          vanadiumWrapper: wrapper
        };
      });

    var sync = this.sync = new TravelSync(vanadiumStartup, {
      maps: maps,
      placesService: map.createPlacesService()
    });
    sync.bindDestinations(destinations);

    this.info(strings['Connecting...'], sync.startup
      .then(function() {
        /* Fit whatever's in the map via timeout to simplify the coding a
         * little. Otherwise we'd need to hook into the asynchronous place
         * vivification and routing. */
        setTimeout(map.fitAll, 2250);
        return strings['Connected to all services.'];
      }));

    var directionsServiceStatusStrings = buildStatusErrorStringMap(
      maps.DirectionsStatus, strings.DirectionsStatus);

    map.onError.add(function(err) {
      var message = directionsServiceStatusStrings[err.directionsStatus] ||
        strings['Unknown error'];

      error(message);
    });

    sync.onError.add(error);
    sync.onMessages.add(function(messages) {
      self.messages.push.apply(self.messages, messages);
    });

    sync.invitationManager.onInvite.add(this.handleInvite);

    messages.onMessage.add(this.handleUserMessage);

    timeline.onAddClick.add(this.handleTimelineDestinationAdd);

    var miniAddButton = this.miniAddButton = new AddButton();
    var miniDestinationSearch = this.miniDestinationSearch =
      new DestinationSearch(maps);

    miniAddButton.onClick.add(this.handleMiniDestinationAdd);

    miniDestinationSearch.setPlaceholder(strings['Search']);
    miniDestinationSearch.setSearchBounds(map.getBounds());
    map.onBoundsChange.add(miniDestinationSearch.setSearchBounds);

    miniDestinationSearch.onSearch.add(function(results) {
      if (results.length > 0) {
        /* If we've searched for a location via the minibox, any subsequent
         * map click is probably intended to deselect the destination rather
         * than pick by clicking. This differs from the timeline behavior since
         * when we invalidate a timeline location, we delete the destination
         * place and so must pick a new one. */
        map.disableLocationSelection();
      }
      map.showSearchResults(results);
    });

    miniDestinationSearch.onPlaceChange.add(function(place) {
      if (!place) {
        self.map.enableLocationSelection();
      }
    });

    miniDestinationSearch.onSubmit.add(function(value) {
      if (!value) {
        var selected = self.map.getSelectedDestination();
        if (selected) {
          selected.remove();
        }

        self.map.clearSearchMarkers();
      }
    });

    var $miniPanel = this.$minPanel = $('<div>')
      .addClass('mini-search')
      .append(miniAddButton.$,
              miniDestinationSearch.$);

    /* This container lets us collapse the destination panel even though it has
     * padding, without resorting to transform: scaleX which would
     * unnecessarily distort the text (which is an effect that is nice for the
     * add button, so that gets it explicitly). */
    var $timelineContainer = this.$timelineContainer = $('<div>')
      .addClass('timeline-container collapsed')
      .append(timeline.$);

    var $toggleTimeline = this.$toggleTimeline = $('<div>')
      .addClass('toggle-timeline no-select collapsed')
      .text(strings['Timeline'])
      .mouseenter(this.showTimeline)
      .click(this.collapseTimeline);

    map.addControls(maps.ControlPosition.TOP_CENTER, messages.$);
    map.addControls(maps.ControlPosition.LEFT_TOP, $miniPanel);
    map.addControls(maps.ControlPosition.LEFT_CENTER, $toggleTimeline);

    var $domRoot = opts.domRoot? $(opts.domRoot) : $('body');

    $domRoot.append($timelineContainer, map.$);

    this.initMiniFeedback();

    destinations.add();
    miniDestinationSearch.focus();

    $domRoot.keypress(function() {
      messages.open();
      /* Somehow emergent behavior types the key just hit without any further
       * code from us. Praise be to the code gods; pray for cross-browser. */
    });

    this.commands = {
      invite: {
        op: this.invite
      },

      status: {
        op: function() {
          this.messages.push(new Message({
            type: Message.INFO,
            html: strings.status(JSON.stringify(this.sync.status, null, 2))
          }));
        }
      }
    };
  }
});

module.exports = Travel;
