    // Yellowcabnyc.com



    // All prices calculated in cents
 
    // the price of travelling one "unit"
    var UNIT_PRICE = 40;
    // The length of a "unit" in miles, if driving over 6 mph
    var UNIT_DISTANCE_MILES = 0.2;

    // The cost of getting in the cab
    var DROP_FEE = 300;
    // The cost of getting in the cab at night
    var LATE_NIGHT_FEE = 50;
    // The cost of getting in the cab during peak hours
    var PEAK_FEE = 100;
    
    // The cost of going to newark
    var NEWARK_FEE = 1500;

     // special flat fee manhattan <--> jfk
     var JFK_PRICE = 4500;

    var newarkPolygon = new GPolygon([
new GLatLng(40.67152478802533, -74.18054580688477),
new GLatLng(40.67647212850004, -74.17230606079102),
new GLatLng(40.685454518757886, -74.16715621948242),
new GLatLng(40.70510741061974, -74.15273666381836),
new GLatLng(40.70875101828792, -74.16183471679688),
new GLatLng(40.70797026199811, -74.17831420898438),
new GLatLng(40.70484714530104, -74.18466567993164),
new GLatLng(40.69014050272525, -74.19307708740234),
new GLatLng(40.67803437027595, -74.19513702392578),
new GLatLng(40.67152478802533, -74.18054580688477)
], "#f33f00", 5, 1, "#ff0000", 0.2);

    var jfkPolygon = new GPolygon([
new GLatLng(40.64704307144758, -73.82246017456055),
new GLatLng(40.662540520807894, -73.82469177246094),
new GLatLng(40.666707287985304, -73.80632400512695),
new GLatLng(40.666446872663194, -73.78726959228516),
new GLatLng(40.651601518462535, -73.7567138671875),
new GLatLng(40.6413120105605, -73.73868942260742),
new GLatLng(40.6328447701751, -73.74847412109375),
new GLatLng(40.61903435155179, -73.7728500366211),
new GLatLng(40.64704307144758, -73.82246017456055)
], "#f33f00", 5, 1, "#ff0000", 0.2);

    var manhattanPolygon = new GPolygon([
new GLatLng(40.8784777276697, -73.92923355102539),
new GLatLng(40.84887829610045, -73.95223617553711),
new GLatLng(40.790419549617724, -73.98828506469727),
new GLatLng(40.75245875985304, -74.01678085327148),
new GLatLng(40.70055262070329, -74.02587890625),
new GLatLng(40.69677841595902, -74.00699615478516),
new GLatLng(40.70523754289766, -73.99669647216797),
new GLatLng(40.70862089287528, -73.97747039794922),
new GLatLng(40.72631561468468, -73.9654541015625),
new GLatLng(40.741924698522055, -73.96820068359375),
new GLatLng(40.753108955872, -73.9610767364502),
new GLatLng(40.76162593648898, -73.9533519744873),
new GLatLng(40.77625179166221, -73.9394474029541),
new GLatLng(40.78216622323578, -73.94176483154297),
new GLatLng(40.792758888618756, -73.93000602722168),
new GLatLng(40.79691751000055, -73.92803192138672),
new GLatLng(40.8018555345511, -73.92794609069824),
new GLatLng(40.80718299114835, -73.93232345581055),
new GLatLng(40.81114582170938, -73.93369674682617),
new GLatLng(40.81894086323425, -73.93318176269531),
new GLatLng(40.83050182122217, -73.93421173095703),
new GLatLng(40.836216606545264, -73.93378257751465),
new GLatLng(40.84439828247503, -73.9295768737793),
new GLatLng(40.85803216472994, -73.91953468322754),
new GLatLng(40.868223282015556, -73.91077995300293),
new GLatLng(40.871922853774734, -73.90966415405273),
new GLatLng(40.8737401115604, -73.91129493713379),
new GLatLng(40.875232821712515, -73.91781806945801),
new GLatLng(40.876660599929764, -73.9211654663086),
new GLatLng(40.8784777276697, -73.92923355102539)
], "#f33f00", 5, 1, "#ff0000", 0.2);

    var laguardiaPolygon = new GPolygon([
new GLatLng(40.781126361334145, -73.88691902160645),
new GLatLng(40.77397687006888, -73.89069557189941),
new GLatLng(40.766826609362575, -73.88777732849121),
new GLatLng(40.76968680597621, -73.87267112731934),
new GLatLng(40.76487640472523, -73.86125564575195),
new GLatLng(40.77254687948199, -73.85147094726562),
new GLatLng(40.780476439378596, -73.86743545532227),
new GLatLng(40.786975372765184, -73.8680362701416),
new GLatLng(40.78470081841747, -73.8764476776123),
new GLatLng(40.781126361334145, -73.88691902160645)
], "#f33f00", 5, 1, "#ff0000", 0.2);

var statenIslandPolygon = new GPolygon([
new GLatLng(40.6504293761137, -74.07188415527344),
new GLatLng(40.6504293761137, -74.07188415527344),
new GLatLng(40.599095409829815, -74.0420150756836),
new GLatLng(40.51445167927482, -74.11514282226562),
new GLatLng(40.48978184687258, -74.25041198730469),
new GLatLng(40.50818718452757, -74.25813674926758),
new GLatLng(40.516670214159504, -74.25212860107422),
new GLatLng(40.53167602215591, -74.24629211425781),
new GLatLng(40.545634930725775, -74.25024032592773),
new GLatLng(40.55789549711741, -74.23238754272461),
new GLatLng(40.55789549711741, -74.21762466430664),
new GLatLng(40.56193838314542, -74.21384811401367),
new GLatLng(40.58853709112115, -74.2071533203125),
new GLatLng(40.598183028351066, -74.19891357421875),
new GLatLng(40.60300547512703, -74.20114517211914),
new GLatLng(40.60860950319387, -74.20492172241211),
new GLatLng(40.61851314776431, -74.20217514038086),
new GLatLng(40.63232367415217, -74.20148849487305),
new GLatLng(40.645349854676944, -74.18621063232422),
new GLatLng(40.64339608963903, -74.12544250488281),
new GLatLng(40.648085029646715, -74.1108512878418),
new GLatLng(40.64821527327774, -74.09231185913086),
new GLatLng(40.651601518462535, -74.08647537231445),
new GLatLng(40.6504293761137, -74.07188415527344)
], "#f33f00", 5, 1, "#ff0000", 0.2);

var newYorkCityPolygon = new GPolygon([
new GLatLng(40.919090487286944, -73.91292572021484),
new GLatLng(40.901576859936284, -73.861083984375),
new GLatLng(40.9127342255246, -73.85026931762695),
new GLatLng(40.89028784209998, -73.84340286254883),
new GLatLng(40.88834126500967, -73.81490707397461),
new GLatLng(40.878088347353184, -73.7786865234375),
new GLatLng(40.832385157167025, -73.77765655517578),
new GLatLng(40.78119135317995, -73.76134872436523),
new GLatLng(40.78574062435701, -73.70710372924805),
new GLatLng(40.707840135059854, -73.72650146484375),
new GLatLng(40.65602942596132, -73.66727828979492),
new GLatLng(40.59257812608643, -73.73405456542969),
new GLatLng(40.53206743305422, -73.9570426940918),
new GLatLng(40.49174010153044, -74.2569351196289),
new GLatLng(40.51575670868556, -74.25470352172852),
new GLatLng(40.52267294048898, -74.24543380737305),
new GLatLng(40.54720023441049, -74.2510986328125),
new GLatLng(40.558678010242645, -74.2317008972168),
new GLatLng(40.55828675482334, -74.21573638916016),
new GLatLng(40.57915051929101, -74.20801162719727),
new GLatLng(40.590101391689515, -74.20646667480469),
new GLatLng(40.60013811627228, -74.1990852355957),
new GLatLng(40.607045635653634, -74.2042350769043),
new GLatLng(40.62489761395493, -74.20303344726562),
new GLatLng(40.63297504354543, -74.20080184936523),
new GLatLng(40.64170278034431, -74.19084548950195),
new GLatLng(40.646652332928745, -74.18106079101562),
new GLatLng(40.64261456761013, -74.14106369018555),
new GLatLng(40.643135583312805, -74.12406921386719),
new GLatLng(40.64834551665458, -74.1108512878418),
new GLatLng(40.64756405258068, -74.09385681152344),
new GLatLng(40.666577080451354, -74.03841018676758),
new GLatLng(40.72462441075683, -74.02090072631836),
new GLatLng(40.771051856415305, -74.00579452514648),
new GLatLng(40.828618431782395, -73.96219253540039),
new GLatLng(40.898592594272095, -73.92477035522461)
], "#f33f00", 5, 1, "#ff0000", 0.2);

    function FeeTotal() {
      var total = 0;
      if (this.jfkPrice != null)
        total += this.jfkPrice;
      if (this.newarkFee != null)
        total += this.newarkFee;
      if (this.unitPrice != null)
        total += this.unitPrice;
      if (this.dropFee != null)
        total += this.dropFee;
      if (this.lateNightFee != null)
        total += this.lateNightFee;
      if (this.peakFee != null)
        total += this.peakFee;
      return total;
    }

    function FeeResults() { 
      this.errorMessage = null;
      this.jfkPrice = null;
      this.newarkFee = null;
      this.unitPrice = null;
      this.dropFee = null;
      this.lateNightFee = null;
      this.peakFee = null;
      this.Total = FeeTotal;
    }

    function unit_fee(distance_miles, duration_seconds) {
      return (distance_miles / UNIT_DISTANCE_MILES) * UNIT_PRICE;
    }
    
    function meters_to_miles(meters) {
      return meters / 1609.3;
    }
    function is_in_newark(latlng) {
      return newarkPolygon.Contains(latlng);
    }

    function is_in_jfk(latlng) {
      return jfkPolygon.Contains(latlng);
    }

    function is_in_laguardia(latlng) {
      return laguardiaPolygon.Contains(latlng);
    }
   
    function is_in_manhattan(latlng) {
      return manhattanPolygon.Contains(latlng);
    }

function is_in_staten_island(latlng) {
  return statenIslandPolygon.Contains(latlng);
}

function is_in_nyc(latlng) {
  return newYorkCityPolygon.Contains(latlng);
}

    function IsInCabRange(placemark) {
      var latlng = new GLatLng(placemark.Point.coordinates[1], placemark.Point.coordinates[0]);
      if (is_in_nyc(latlng) || is_in_newark(latlng)) {
        return true;
      } 
      if (!placemark.AddressDetails || !placemark.AddressDetails.Country || !placemark.AddressDetails.Country.AdministrativeArea)
        return false;
      var adminArea = placemark.AddressDetails.Country.AdministrativeArea;
      var adminAreaName = adminArea.AdministrativeAreaName;
      var locality = null;
      if (adminArea.Locality) {
        locality = adminArea.Locality.LocalityName;
      } else if (adminArea.SubAdministrativeArea != null && adminArea.SubAdministrativeArea.Locality != null) {
        locality = adminArea.SubAdministrativeArea.Locality.LocalityName;
      } else {
        return false;
      }
      return (adminAreaName == 'NY' && (locality == 'Queens' || locality == 'New York' || locality == 'Bronx' || locality == 'Staten Island' || locality == 'Brooklyn')) || (adminAreaName == 'NJ' && locality == 'Elizabeth');
    }


    function calculate_fees(duration_seconds, distance_meters, route, is_peak, is_night) {
      var dest_lat_lng = route.getStep(0).getLatLng();
      var from_lat_lng = route.getEndLatLng();
      var results = new FeeResults();
      if (!IsInCabRange(route.getEndGeocode())) {
        results.errorMessage = "Destination is not in the five boroughs or Newark, so the price must be negotiated with the driver.";
        return results;
      }
      if (!IsInCabRange(route.getStartGeocode())) {
        results.errorMessage = "Starting location is not in the five boroughs or Newark, so the price must be negotiated with the driver.";
        return results;
      }
      if ((is_in_jfk(dest_lat_lng) && is_in_manhattan(from_lat_lng))
         || (is_in_jfk(from_lat_lng) && is_in_manhattan(dest_lat_lng))) {
        results.jfkPrice = JFK_PRICE;
        return results;
      }
      if (is_peak) {
        results.peakFee = PEAK_FEE;
      }
      if (is_night) {
        results.lateNightFee = LATE_NIGHT_FEE;
      }
      if (is_in_newark(dest_lat_lng) || is_in_newark(from_lat_lng)) {
        results.newarkFee = NEWARK_FEE;
      }
      results.unitPrice = unit_fee(meters_to_miles(distance_meters), duration_seconds);
      results.dropFee = DROP_FEE;
      return results;
    }

    function calculate_fees_from_directions(the_directions, is_peak, is_night) {
      var route = the_directions.getRoute(0);
      return calculate_fees(the_directions.getDuration().seconds, gdir.getDistance().meters, route, is_peak, is_night);
    }
