// 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 defineClass = require('./util/define-class');

var Place = defineClass({
  statics: {
    fromObject: function(dependencies, obj) {
      var async = new Deferred();

      if (obj.placeId) {
        dependencies.placesService.getDetails(obj, function(place, status) {
          if (status === dependencies.maps.places.PlacesServiceStatus.OK) {
            async.resolve(new Place(place));
          } else {
            async.reject(status);
          }
        });
      } else {
        async.reject('Deserialization not supported.'); //TODO(rosswang)
      }

      return async.promise;
    }
  },

  publics: {
    getDetails: function() {
      return this.details;
    },

    hasDetails: function() {
      return !!this.details;
    },

    getGeometry: function() {
      return this.details && this.details.geometry || {
        location: this.getLocation()
      };
    },

    getLocation: function() {
      return this.placeObj.location;
    },

    getName: function() {
      var details = this.details;
      return details && details.name ||
        /[^,]*/.exec(details['formatted_address'])[0];
    },

    getPlaceObject: function() {
      return this.placeObj;
    },

    getSingleLine: function() {
      var details = this.details;

      if (this.singleLine) {
        return this.singleLine;

      } else if (details) {
        this.singleLine = details.name &&
          details.name !== details['formatted_address'].split(', ')[0]?
            details.name + ', ' + details['formatted_address'] :
            details['formatted_address'];
        return this.singleLine;

      } else { // not preferred
        return this.placeObj.query || this.placeObj.location.toString();
      }
    },

    /**
     * This code is highly fragile and heaven help the poor soul who needs to
     * localize it.
     *
     * TODO(rosswang): Is this really the best way? We should find a formatter.
     *
     * @param name optional place name to omit from the address. Defaults to the
     *   name in the details; pass null to override.
     * @return an array of formatted address lines.
     */
    getMultiLine: function(name) {
      var details = this.details;

      var addr = details && details['formatted_address'];
      if (!addr) {
        return [];
      }

      if (name === undefined) {
        name = details.name;
      }

      /* If at any point the first line/atom will echo the place name, leave it
       * out. */

      var parts = addr.split(', ');
      var lines = (function() {
        switch (parts.length) {
          case 2:
            // ex. WA, USA => WA, USA
            return [parts.join(', ')];
          case 3:
            // ex. Seattle, WA, USA => Seattle, WA || WA, USA
            // (if Seattle was the search query, format as if it were WA, USA)
            return parts[0] === name?
              [parts[1] + ', ' + parts[2]] : [parts[0] + ', ' + parts[1]];
          case 4: {
            /* ex. Amphitheatre Pkwy, Mountain View, CA 94043, USA:
             *
             * Amphitheatre Pkwy
             * Mountain View, CA 94043
             */
            return [parts[0], parts[1] + ', ' + parts[2]];
          }
          case 5: {
            /* ex. Fort Mason, 2 Marina Blvd, San Francisco, CA 94123, USA
             *
             * Fort Mason
             * 2 Marina Blvd
             * San Francisco, CA 94123
             */
            return [parts[0], parts[1], parts[2] + ', ' + parts[3]];
          }
          case 6: {
            /* ex. A, Fort Mason, 2 Marina Blvd, San Francisco, CA 94123, USA
             *
             * A, Fort Mason
             * 2 Marina Blvd
             * San Francisco, CA 94123
             */
            return [
              parts[0] + ', ' + parts[1],
              parts[2],
              parts[3] + ', ' + parts[4]
            ];
          }
          default:
            return parts;
        }
      })();

      return lines[0] === name? lines.slice(1) : lines;
    },

    /**
     * Returns a plain object that can be used to reconstruct the place. This
     * object really shouldn't be mutated.
     */
    toObject: function() {
      if (this.placeObj.placeId) {
        return {
          placeId: this.placeObj.placeId
        };
      } else {
        return {
          location: {
            lat: this.placeObj.location.lat(),
            lng: this.placeObj.location.lng()
          },
          query: this.placeObj.query
        };
      }
    },

    toKey: function() {
      return this.placeObj.placeId ||
        (this.placeObj.query || '') + this.placeObj.location.toString();
    }
  },

  /**
   * @param desc place object, place details result, or search result.
   *
   * TODO(rosswang): lazy fetch details if not given.
   */
  init: function(desc) {
    if (desc.geometry) {
      var placeObj = this.placeObj = { location: desc.geometry.location };
      this.details = desc;

      if (desc['place_id'] !== undefined) {
        placeObj.placeId = desc['place_id'];
      } else {
        placeObj.query = desc['formatted_address'];
      }
    } else {
      this.placeObj = desc;
    }
  }
});

module.exports = Place;