WME Place Interface Enhancements

Enhancements to various Place interfaces

À partir de 2017-01-16. Voir la dernière version.

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name         WME Place Interface Enhancements
// @namespace    https://greatest.deepsurf.us/users/30701-justins83-waze
// @version      0.6.1
// @description  Enhancements to various Place interfaces
// @include      https://www.waze.com/editor/*
// @include      https://www.waze.com/*/editor/*
// @include      https://beta.waze.com/*
// @exclude      https://www.waze.com/user/editor*
// @author       JustinS83
// @grant        none
// @require      https://greatest.deepsurf.us/scripts/24851-wazewrap/code/WazeWrap.js
// @license      GPLv3
// ==/UserScript==
var UpdateObject, MultiAction;

(function() {
    'use strict';

    var settings = {};
    var placeMenuSelector = "#edit-buttons > div > div.toolbar-button.waze-icon-place.toolbar-submenu.toolbar-group.toolbar-group-venues.ItemInactive > menu";
    var pointStyle = {
			pointRadius: 6,
			fillOpacity: 0,
			strokeColor: '#00ece3',
			strokeWidth: '2',
			strokeLinecap: 'round'
		};
    var layerName = "WME PIE";
    var newPlaceLayer;
    var placementMode = false;
    var drawPoly;

    // Your code here...
    function bootstrap(tries) {
        tries = tries || 1;

        if (window.W &&
            window.W.map &&
            window.W.model &&
            $) {
            init();
        } else if (tries < 1000) {
            setTimeout(function () {bootstrap(tries++);}, 200);
        }
    }

    bootstrap();

    function init(){
        var $section = $("<div>", {style:"padding:8px 16px", id:"WMEPIESettings"});
        $section.html([
            '<h4><b>WME Place Interface Enhancements</b></h4>',
            '<div class="controls-container" id="divAreaPlaceSizeControls">',
            '<div id="divShowAreaPlaceSize" class="controls-container"><input type="checkbox" id="_cbShowAreaPlaceSize" class="pieSettingsCheckbox" /><label for="_cbShowAreaPlaceSize">Show area Place size</label></div>',
            '<div id="divShowAreaPlaceSizeImperial"class="controls-container" style="padding-left:30px;"><input type="checkbox" id="_cbShowAreaPlaceSizeImperial" class="pieSettingsCheckbox" disabled /><label for ="_cbShowAreaPlaceSizeImperial"> Show imperial </label></div>',
            '<div id="divShowAreaPlaceSizeMetric" class="controls-container" style="padding-left:30px;"><input type="checkbox" id="_cbShowAreaPlaceSizeMetric" class="pieSettingsCheckbox" disabled /><label for ="_cbShowAreaPlaceSizeMetric"> Show metric</label></div>',
            '</div>',
            '<div class="controls-container" id="divShowLockButtonsRPP" title="Displays lock level buttons for Residential Place Points"><input type="checkbox" id="_cbShowLockButtonsRPP" class="pieSettingsCheckbox" /><label for="_cbShowLockButtonsRPP">Show lock buttons for RPPs</label></div>',
            '<div class="controls-container" id="divShowPlaceLocatorCrosshair" title="Centers the Place on screen and zooms to the defined level" ><input type="checkbox" id="_cbShowPlaceLocatorCrosshair" class="pieSettingsCheckbox" /><label for="_cbShowPlaceLocatorCrosshair">Show Place locator crosshair</label></br>',
            '<span class="controls-container" style="padding-left:30px;" title="The zoom level to use when centering on a Place">Zoom <select id="piePlaceZoom"><option value="10">10</option><option value="9">9</option><option value="8">8</option><option value="7">7</option><option value="6">6</option><option value="5">5</option><option value="4">4</option><option value="3">3</option><option value="2">2</option><option value="1">1</option><option value="0">0</option></select></span></div>',
            '<b>New Places</b></br>',
            '<div id="divEditRPPAfterCreated" class="controls-container" title="Automatically opens the RPP address edit window and focuses on the House Number entry"><input type="checkbox" id="_cbEditRPPAfterCreated" class="pieSettingsCheckbox"><label for="_cbEditRPPAfterCreated">Edit RPP address after created</label></div>',
            '<div id="divUseStreetFromClosestSeg" class="controls-container" title="Pulls the street name from the closest visible segment and inserts into the new Place&quot;s address"><input type="checkbox" id="_cbUseStreetFromClosestSeg" class="pieSettingsCheckbox"><label for="_cbUseStreetFromClosestSeg">Use street name from closest segment</label></div>',
            '<div id="divUseCityFromClosestSeg" class="controls-container" title="Pulls the city name from the closest visible segment and inserts into the new Place&quot;s address"><input type="checkbox" id="_cbUseCityFromClosestSeg" class="pieSettingsCheckbox"><label for="_cbUseCityFromClosestSeg">Use city name from closest segment</label></div>',
            '<div id="divDefaultLockLevel" class="controls-container" title="The lock level to set automatically when creating new Places">Lock Level <select id="pieDefaultLockLevel">' + buildLockLevelsList() + '</select></div>',
            '<div class="controls-container" id="divPlaceMenuCustomization">',
            '<b>Place Menu Customization</b></br>',
            buildItemOption(1),
            buildItemOption(2),
            buildItemOption(3),
            buildItemOption(4),
            buildItemOption(5),
            buildItemOption(6),
            buildItemOption(7),
            buildItemOption(8),
            buildItemOption(9),
            buildItemOption(10),
            buildItemOption(11),
            '</div>'

        ].join(' '));

        UpdateObject = require("Waze/Action/UpdateObject");
        MultiAction = require("Waze/Action/MultiAction");

        newPlaceLayer = new OL.Layer.Vector(layerName,{displayInLayerSwitcher: false});
		W.map.addLayer(newPlaceLayer);

        injectCss();
        new WazeWrap.Interface.Tab('PIE', $section.html(), init2);
    }

    function buildNewPlaceList(){
        //Clear out the Places menu
        $('#edit-buttons > div > div.toolbar-button.waze-icon-place.toolbar-submenu.toolbar-group.toolbar-group-venues.ItemInactive > menu').empty();
        var cat = "";
        var i;
        for(i=0;i<11;i++){
            cat = $('#pieItem' + (i+1))[0].value;
            if(cat !== "PARKING_LOT" && cat !== "RESIDENCE_HOME")
                $(placeMenuSelector).append('<div class="toolbar-group-item WazeControlDrawFeature ItemInactive" id="piePlaceMainItem' + (i+1) + '" data-category="'+ cat + '"><span class="menu-title">' + $('#pieItem' + (i+1))[0].options[$('#pieItem' + (i+1))[0].selectedIndex].innerHTML + '</span><div class="drawing-controls"><span class="drawing-control polygon secondary-control" id="piePlaceAreaItem' + (i+1) + '" data-category="' + cat + '" title="Place (area)"></span><span class="drawing-control main-control point" id="piePlacePointItem' + (i+1) + '" data-category="' + cat + '" title="Place (point)"></span></div></div>');
            else{
                if(cat === "RESIDENCE_HOME") //force point
                    $(placeMenuSelector).append('<div class="toolbar-group-item WazeControlDrawFeature ItemInactive" id="piePlaceMainItem' + (i+1) + '" data-category="'+ cat + '"><span class="menu-title">' + $('#pieItem' + (i+1))[0].options[$('#pieItem' + (i+1))[0].selectedIndex].innerHTML + '</span></div>');
                else //Parking lot - force area
                    $(placeMenuSelector).append('<div class="toolbar-group-item WazeControlDrawFeature ItemInactive" id="piePlaceAreaItem' + (i+1) + '" data-category="'+ cat + '"><span class="menu-title">' + $('#pieItem' + (i+1))[0].options[$('#pieItem' + (i+1))[0].selectedIndex].innerHTML + '</span></div>');
            }
        }

        $('[id^="piePlaceMainItem"]').click(function(e){
            startPlacementMode($('#' + this.id).data("category"), true);
        });

        $('[id^="piePlaceAreaItem"]').click(function(e){
            e.stopPropagation();
            startPlacementMode($('#' + this.id).data("category"), false);
        });
    }

    function init2(){
        //Load settings
        loadSettings();
        //Set up event handlers
        $('#_cbShowAreaPlaceSize').change(function() {
            if(this.checked) {
                attachPlaceSizeHandlers();
                updatePlaceSizeDisplay();
                $('#_cbShowAreaPlaceSizeImperial')[0].disabled = false;
                $('#_cbShowAreaPlaceSizeMetric')[0].disabled = false;
            }
            else
            {
                removePlaceSizeHandlers();
                $('#AreaSize').remove();
                $('#_cbShowAreaPlaceSizeImperial')[0].disabled = true;
                $('#_cbShowAreaPlaceSizeMetric')[0].disabled = true;
            }
        });

        $('#_cbShowLockButtonsRPP').change(function() {
            if(this.checked) {
                attachRPPLockButtonHandlers();
            }
            else
            {
                $('#pieRPPLockButtonsContainer').remove();
                W.selectionManager.events.unregister("selectionchanged", null, addLockButtons);
                W.model.actionManager.events.unregister("afterundoaction",null, addLockButtons);
                W.model.actionManager.events.unregister("afterclearactions",null, addLockButtons);
                W.model.actionManager.events.unregister("afteraction",null, addLockButtons);
            }
        });

        $('#_cbShowPlaceLocatorCrosshair').change(function(){
            if(this.checked){
                W.selectionManager.events.register("selectionchanged", null, ShowPlaceLocatorCrosshair);
                W.model.actionManager.events.register("afterundoaction",null, ShowPlaceLocatorCrosshair);
                W.model.actionManager.events.register("afterclearactions",null, ShowPlaceLocatorCrosshair);
                W.model.actionManager.events.register("afteraction",null, ShowPlaceLocatorCrosshair);
            }
            else{
                W.selectionManager.events.unregister("selectionchanged", null, ShowPlaceLocatorCrosshair);
                W.model.actionManager.events.unregister("afterundoaction",null, ShowPlaceLocatorCrosshair);
                W.model.actionManager.events.unregister("afterclearactions",null, ShowPlaceLocatorCrosshair);
                W.model.actionManager.events.unregister("afteraction",null, ShowPlaceLocatorCrosshair);
            }
        });

        //Load settings to interface
        setChecked('_cbShowAreaPlaceSize', settings.ShowAreaPlaceSize);
        setChecked('_cbShowAreaPlaceSizeImperial', settings.ShowAreaPlaceSizeImperial);
        setChecked('_cbShowAreaPlaceSizeMetric', settings.ShowAreaPlaceSizeMetric);
        setChecked('_cbShowLockButtonsRPP', settings.ShowLockButtonsRPP);
        setChecked('_cbEditRPPAfterCreated', settings.EditRPPAfterCreated);
        setChecked('_cbUseStreetFromClosestSeg', settings.UseStreetFromClosestSeg);
        setChecked('_cbUseCityFromClosestSeg', settings.UseCityFromClosestSeg);
        setChecked('_cbShowPlaceLocatorCrosshair', settings.ShowPlaceLocatorCrosshair);
        $('#piePlaceZoom')[0].value = settings.PlaceZoom;
        $('#pieDefaultLockLevel')[0].value = settings.DefaultLockLevel;

        if(settings.ShowAreaPlaceSize){
            $('#_cbShowAreaPlaceSizeImperial')[0].disabled = false;
            $('#_cbShowAreaPlaceSizeMetric')[0].disabled = false;
            attachPlaceSizeHandlers();
        }

        if(settings.ShowPlaceLocatorCrosshair){
            W.selectionManager.events.register("selectionchanged", null, ShowPlaceLocatorCrosshair);
            W.model.actionManager.events.register("afterundoaction",null, ShowPlaceLocatorCrosshair);
            W.model.actionManager.events.register("afterclearactions",null, ShowPlaceLocatorCrosshair);
            W.model.actionManager.events.register("afteraction",null, ShowPlaceLocatorCrosshair);
            ShowPlaceLocatorCrosshair(); //in case the user opened a PL with a Place selected
        }

        if(settings.ShowLockButtonsRPP)
            attachRPPLockButtonHandlers();

        $('.pieSettingsCheckbox').change(function() {
             var settingName = $(this)[0].id.substr(3);
            settings[settingName] = this.checked;
            saveSettings();
        });

        $('#piePlaceZoom').change(function(){
            var settingName = $(this)[0].id.substr(3);
            settings[settingName] = $(this)[0].value;
            saveSettings();
        });

        $('#pieDefaultLockLevel').change(function(){
            settings[$(this)[0].id.substr(3)] = $(this)[0].value;
            saveSettings();
        });

        var i;
        //Whenever a Place item is changed, read the settings and save to localStorage
        $('[id^="pieItem"]').change(function(){
            for(i=0;i<11;i++){
                settings.NewPlacesList[i] = $('#pieItem'+(i+1))[0].value;
            }
            saveSettings();
            buildNewPlaceList();
        });

        //Load settings into Place Customization list options
        for(i=0; i<11;i++)
            $('#pieItem'+(i+1))[0].value = settings.NewPlacesList[i];

        //Build our new menu
        buildNewPlaceList();

        //new WazeWrap.Interface.Shortcut('Create Residential Place', 'Place Interface Enhancements', 'A+r', function(){startPlacementMode("RESIDENCE_HOME", true);}, this).add();
    }

    var areaCategory = "";
    function startPlacementMode(category, isPoint){
        $('#edit-buttons > div > div.toolbar-button.waze-icon-place.toolbar-submenu.toolbar-group.toolbar-group-venues.ItemInactive').removeClass("open");
        if(isPoint){
            $("#map").on('mousemove', MouseMoveHandler);
            $("#map").click(function(){endPlacementMode(category, isPoint);});
        }
        else{
            areaCategory = category;
            var polyDrawFeatureOptions = {callbacks : {"done": doneHandler}};
            drawPoly = new OpenLayers.Control.DrawFeature(newPlaceLayer, OpenLayers.Handler.Polygon, polyDrawFeatureOptions);
            W.map.addControl(drawPoly);
            drawPoly.activate();

        }
        document.addEventListener('keyup', keyUpHandler, false);
    }

    function doneHandler(geom){
        drawPoly.destroy();
        createPlace(geom, areaCategory, false);
    }

    function keyUpHandler(e){
         if (e.keyCode == 27){
             disablePlacementMode();
             if(drawPoly !== "undefined")
                 drawPoly.destroy();
         }
        else if(e.keyCode == 90 && e.ctrlKey)
            drawPoly.undo();
        else if(e.keyCode == 89 && e.ctrlKey)
            drawPoly.redo();
        else if(e.keyCode == 13)
            drawPoly.finishSketch();
    }

    function disablePlacementMode(){
        $("#map").off('click');//, endPlacementMode);
        $("#map").off('mousemove', MouseMoveHandler);
        clearLayer();
        document.removeEventListener('keyup', keyUpHandler);
    }

    function endPlacementMode(category, isPoint){
        disablePlacementMode();
        createPlace(getMousePos900913(), category, isPoint);
    }

    function getMousePos900913(){
        var mousePosition = $('.WazeControlMousePosition').text().split(" ");
        return WazeWrap.Geometry.ConvertTo900913(mousePosition[0], mousePosition[1]);
    }

    function MouseMoveHandler(e){
        clearLayer();
		drawCircle(getMousePos900913());
    }

    function clearLayer() {
		var layer = W.map.getLayersByName(layerName)[0];
		layer.removeAllFeatures();
	}

    function drawCircle(e){
        var pointFeature = new OL.Feature.Vector(new OL.Geometry.Point(e.lon, e.lat), {}, pointStyle);
		W.map.getLayersByName(layerName)[0].addFeatures([pointFeature]);
    }

    function createPlace(pos, category, isPoint){
        var PlaceObject = require("Waze/Feature/Vector/Landmark");
        var AddPlace = require("Waze/Action/AddLandmark");
        var multiaction = new MultiAction();
        multiaction.setModel(W.model);

        var NewPlace = new PlaceObject();
        if(isPoint)
            NewPlace.geometry = new OL.Geometry.Point(pos.lon, pos.lat);
        else{
            var points = [];
            var i;
            for(i=0;i<pos.components[0].components.length;i++){
                points.push(new OL.Geometry.Point(pos.components[0].components[i].x, pos.components[0].components[i].y));
            }
            var ring = new OpenLayers.Geometry.LinearRing(points);
            NewPlace.geometry = new OL.Geometry.Polygon([ring]);

        }

        NewPlace.attributes.categories.push(category);
        if(category === "RESIDENCE_HOME"){
            NewPlace._originalResidential = true;
            NewPlace.attributes.residential = true;
        }
        NewPlace.attributes.lockRank = Number(settings.DefaultLockLevel);

        var closestSeg = WazeWrap.Geometry.findClosestSegment(new OL.Geometry.Point(pos.lon, pos.lat));

        W.model.actionManager.add(new AddPlace(NewPlace));
        Waze.selectionManager.select([NewPlace]);

        if(closestSeg){ //if we were able to find a segment, try to pull the city and/or street name if the options are enabled
            var newAttributes, UpdateFeatureAddress = require('Waze/Action/UpdateFeatureAddress'), address = closestSeg.getAddress();

            newAttributes = {
                countryID: address.country.id,
                stateID: address.state.id,
                emptyCity: address.city.attributes.name ? null : true,
                emptyStreet: address.street.name ? null : true
            };

            if(settings.UseStreetFromClosestSeg)
                newAttributes.streetName = address.street.name;
            else
                newAttributes.emptyStreet = true;

            if(settings.UseCityFromClosestSeg)
                newAttributes.cityName = address.city.attributes.name;
            else
                newAttributes.emptyCity = true;

            multiaction.doSubAction(new UpdateFeatureAddress(NewPlace, newAttributes));
            W.model.actionManager.add(multiaction);
        }
        else
            console.log("WMEPIE - No segment found; cannot set street or city name.");

        if(category === "RESIDENCE_HOME" && settings.EditRPPAfterCreated)
            editRPPAddress();
    }

    function editRPPAddress(rppTries){
        rppTries = rppTries || 1;

        if ($('.edit-button').length > 0) {
            $('.edit-button').trigger("click");
            $('.house-number:first').focus();

        } else if (rppTries < 1000) {
            console.log("not found");
            setTimeout(function () {editRPPAddress(rppTries++);}, 200);
        }
    }

    function buildItemOption(itemNumber){
        var $section = $("<div>", {style:"padding:8px 16px", id:"piePlaceCat" + itemNumber});
        $section.html([
            'Item ',
            itemNumber,
            buildItemList(itemNumber),
            '</br>'
            ].join(' '));

        return $section.html();
    }

    function buildLockLevelsList(){
        var $lockLevels = $("<div>");
        for(var i=0;i<WazeWrap.User.Rank();i++){
            $lockLevels.append("<option value=" + i + ">" + (i+1) + "</option>");
        }
        return $lockLevels.html();
    }

    function buildItemList(itemNumber){

        var $places = $("<div>");
        $places.html([
            '<select id="pieItem' + itemNumber + '">',
            '<option value="CAR_SERVICES" style="font-weight:bold;">Car Services</option>',
            '<option value="GAS_STATION">Gas Station</option>',
            '<option value="GARAGE_AUTOMOTIVE_SHOP">Garage / Automotive Shop</option>',
            '<option value="CAR_WASH">Car Wash</option>',
            '<option value="CHARGING_STATION">Charging Station</option>',
            '<option value="TRANSPORTATION" style="font-weight:bold;">Transportation</option>',
            '<option value="AIRPORT">Airport</option>',
            '<option value="BUS_STATION">Bus Station</option>',
            '<option value="FERRY_PIER">Ferry Pier</option>',
            '<option value="SEAPORT_MARINA_HARBOR">Seaport / Marina / Harbor</option>',
            '<option value="SUBWAY_STATION">Subway Station</option>',
            '<option value="TRAIN_STATION">Train Station</option>',
            '<option value="BRIDGE">Bridge</option>',
            '<option value="TUNNEL">Tunnel</option>',
            '<option value="TAXI_STATION">Taxi Station</option>',
            '<option value="JUNCTION_INTERCHANGE">Junction / Interchange</option>',
            '<option value="PROFESSIONAL_AND_PUBLIC" style="font-weight:bold;">Professional and public</option>',
            '<option value="COLLEGE_UNIVERSITY">College / University</option>',
            '<option value="SCHOOL">School</option>',
            '<option value="CONVENTIONS_EVENT_CENTER">Conventions / Event Center</option>',
            '<option value="GOVERNMENT">Government</option>',
            '<option value="LIBRARY">Library</option>',
            '<option value="CITY_HALL">City Hall</option>',
            '<option value="ORGANIZATION_OR_ASSOCIATION">Organization or Association</option>',
            '<option value="PRISON_CORRECTIONAL_FACILITY">Prison / Correctional Facility</option>',
            '<option value="COURTHOUSE">Courthouse</option>',
            '<option value="CEMETERY">Cemetery</option>',
            '<option value="FIRE_DEPARTMENT">Fire Department</option>',
            '<option value="POLICE_STATION">Police Station</option>',
            '<option value="MILITARY">Military</option>',
            '<option value="HOSPITAL_MEDICAL_CARE">Hospital / Medical Care</option>',
            '<option value="OFFICES">Offices</option>',
            '<option value="POST_OFFICE">Post Office</option>',
            '<option value="RELIGIOUS_CENTER">Religious Center</option>',
            '<option value="KINDERGARTEN">Kindergarten</option>',
            '<option value="FACTORY_INDUSTRIAL">Factory / Industrial</option>',
            '<option value="EMBASSY_CONSULATE">Embassy / Consulate</option>',
            '<option value="INFORMATION_POINT">Information Point</option>',
            '<option value="EMERGENCY_SHELTER">Emergency Shelter</option>',
            '<option value="SHOPPING_AND_SERVICES" style="font-weight:bold;">Shopping and services</option>',
            '<option value="ARTS_AND_CRAFTS">Arts & Crafts</option>',
            '<option value="BANK_FINANCIAL">Bank / Financial</option>',
            '<option value="SPORTING_GOODS">Sporting Goods</option>',
            '<option value="BOOKSTORE">Bookstore</option>',
            '<option value="PHOTOGRAPHY">Photography</option>',
            '<option value="CAR_DEALERSHIP">Car Dealership</option>',
            '<option value="FASHION_AND_CLOTHING">Fashion and Clothing</option>',
            '<option value="CONVENIENCE_STORE">Convenience Store</option>',
            '<option value="PERSONAL_CARE">Personal Care</option>',
            '<option value="DEPARTMENT_STORE">Department Store</option>',
            '<option value="PHARMACY">Pharmacy</option>',
            '<option value="ELECTRONICS">Electronics</option>',
            '<option value="FLOWERS">Flowers</option>',
            '<option value="FURNITURE_HOME_STORE">Furniture / Home Store</option>',
            '<option value="GIFTS">Gifts</option>',
            '<option value="GYM_FITNESS">Gym / Fitness</option>',
            '<option value="SWIMMING_POOL">Swimming Pool</option>',
            '<option value="HARDWARE_STORE">Hardware Store</option>',
            '<option value="MARKET">Market</option>',
            '<option value="SUPERMARKET_GROCERY">Supermarket / Grocery</option>',
            '<option value="JEWELRY">Jewelry</option>',
            '<option value="LAUNDRY_DRY_CLEAN">Laundry / Dry Clean</option>',
            '<option value="SHOPPING_CENTER">Shopping Center</option>',
            '<option value="MUSIC_STORE">Music Store</option>',
            '<option value="PET_STORE_VETERINARIAN_SERVICES">Pet Store / Veterinarian Services</option>',
            '<option value="TOY_STORE">Toy Store</option>',
            '<option value="TRAVEL_AGENCY">Travel Agency</option>',
            '<option value="ATM">ATM</option>',
            '<option value="CURRENCY_EXCHANGE">Currency Exchange</option>',
            '<option value="CAR_RENTAL">Car Rental</option>',
            '<option value="FOOD_AND_DRINK" style="font-weight:bold;">Food and Drink</option>',
            '<option value="RESTAURANT">Restaurant</option>',
            '<option value="BAKERY">Bakery</option>',
            '<option value="DESSERT">Dessert</option>',
            '<option value="CAFE">Coffee shop</option>',
            '<option value="FAST_FOOD">Fast Food</option>',
            '<option value="FOOD_COURT">Food Court</option>',
            '<option value="BAR">Bar</option>',
            '<option value="ICE_CREAM">Ice Cream</option>',
            '<option value="CULTURE_AND_ENTERTAINEMENT" style="font-weight:bold;">Culture & Entertainment</option>',
            '<option value="ART_GALLERY">Art Gallery</option>',
            '<option value="CASINO">Casino</option>',
            '<option value="CLUB">Club</option>',
            '<option value="TOURIST_ATTRACTION_HISTORIC_SITE">Tourist Attraction / Historic Site</option>',
            '<option value="MOVIE_THEATER">Movie Theater</option>',
            '<option value="MUSEUM">Museum</option>',
            '<option value="MUSIC_VENUE">Music Venue</option>',
            '<option value="PERFORMING_ARTS_VENUE">Performing Arts Venue</option>',
            '<option value="GAME_CLUB">Game Club</option>',
            '<option value="STADIUM_ARENA">Stadium / Arena</option>',
            '<option value="THEME_PARK">Theme Park</option>',
            '<option value="ZOO_AQUARIUM">Zoo / Aquarium</option>',
            '<option value="RACING_TRACK">Racing Track</option>',
            '<option value="THEATER">Theater</option>',
            '<option value="OTHER" style="font-weight:bold;">Other</option>',
            '<option value="CONSTRUCTION_SITE">Construction Site</option>',
            '<option value="LODGING" style="font-weight:bold;">Lodging</option>',
            '<option value="HOTEL">Hotel</option>',
            '<option value="HOSTEL">Hostel</option>',
            '<option value="CAMPING_TRAILER_PARK">Camping / Trailer Park</option>',
            '<option value="COTTAGE_CABIN">Cottage / Cabin</option>',
            '<option value="BED_AND_BREAKFAST">Bed & Breakfast</option>',
            '<option value="OUTDOORS" style="font-weight:bold;">Outdoors</option>',
            '<option value="PARK">Park</option>',
            '<option value="PLAYGROUND">Playground</option>',
            '<option value="BEACH">Beach</option>',
            '<option value="SPORTS_COURT">Sports Court</option>',
            '<option value="GOLF_COURSE">Golf Course</option>',
            '<option value="PLAZA">Plaza</option>',
            '<option value="PROMENADE">Promenade</option>',
            '<option value="POOL">Pool</option>',
            '<option value="SCENIC_LOOKOUT_VIEWPOINT">Scenic Lookout / Viewpoint</option>',
            '<option value="SKI_AREA">Ski Area</option>',
            '<option value="NATURAL_FEATURES" style="font-weight:bold;">Natural Features</option>',
            '<option value="ISLAND">Island</option>',
            '<option value="SEA_LAKE_POOL">Sea / Lake / Pool</option>',
            '<option value="RIVER_STREAM">River / Stream</option>',
            '<option value="FOREST_GROVE">Forest / Grove</option>',
            '<option value="FARM">Farm</option>',
            '<option value="CANAL">Canal</option>',
            '<option value="SWAMP_MARSH">Swamp / Marsh</option>',
            '<option value="DAM">Dam</option>',
            '<option value="PARKING_LOT" style="font-weight:bold;">Parking Lot</option>',
            '<option value="RESIDENCE_HOME" style="font-weight:bold;">Residential</option>',
            '</select>'
            ].join(' '));

        return $places.html();
    }

    function attachRPPLockButtonHandlers(){
        $('#pieRPPLockButtonsContainer').remove();
        W.selectionManager.events.register("selectionchanged", null, addLockButtons);
        W.model.actionManager.events.register("afterundoaction",null, addLockButtons);
        W.model.actionManager.events.register("afterclearactions",null, addLockButtons);
        W.model.actionManager.events.register("afteraction",null, addLockButtons);
    }

    function attachPlaceSizeHandlers(){
        W.selectionManager.events.register("selectionchanged", null, updatePlaceSizeDisplay);
        W.model.actionManager.events.register("afteraction",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.register("afterundoaction",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.register("afterclearactions",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.register("noActions",null, noActions);
        updatePlaceSizeDisplay();
    }

    function removePlaceSizeHandlers(){
        W.selectionManager.events.unregister("selectionchanged", null, updatePlaceSizeDisplay);
        W.model.actionManager.events.unregister("afteraction",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.unregister("afterundoaction",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.unregister("afterclearactions",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.unregister("noActions",null, noActions);
    }

    function ShowPlaceLocatorCrosshair(){
        $('#pieCrosshairs').remove();
        if(W.selectionManager.selectedItems.length > 0){
            if(W.selectionManager.selectedItems[0].model.type === "venue"){
                var panelWidth = $('#landmark-edit-general').width();
                var $crosshairs = $('<div style="float:right;z-index:100;cursor: pointer;" id="pieCrosshairs" title="Zoom and center on Place"><i class="fa fa-crosshairs fa-lg" aria-hidden="true"></i></div>');
                $('#landmark-edit-general > form > div:nth-child(1) > i').after($crosshairs);
                $('#pieCrosshairs').click(function(){
                    CenterOnPlace(W.selectionManager.selectedItems[0].model, settings.PlaceZoom);
                });
            }
        }
    }

    function CenterOnPlace(venue, zoom){
        var centroid = venue.geometry.getCentroid();
        W.map.setCenter([centroid.x, centroid.y], zoom);
    }

    function isChecked(checkboxId) {
        return $('#' + checkboxId).is(':checked');
    }

    function setChecked(checkboxId, checked) {
        $('#' + checkboxId).prop('checked', checked);
    }

    function noActions(){
        setTimeout(updatePlaceSizeDisplay, 100 ); //have to put in a delay for when the user uses undo to clear all actions - WME updates on top of my changes otherwise.
    }

    function updatePlaceSizeDisplay(){
        var count = W.selectionManager.selectedItems.length;
        var metersArea = 0;
        var bold = false;
        if(count === 1){
           var venue = W.selectionManager.selectedItems[0];
           var isArea = venue.geometry.toString().match(/^POLYGON/);
           //var isPoint = venue.geometry.toString().match(/^POINT/);

            if(venue.model.type === "venue" && isArea){
                if($('#AreaSize'))
                    $('#AreaSize').remove();
                metersArea = W.selectionManager.selectedItems[0].model.geometry.getGeodesicArea(W.map.getProjectionObject());

                if(metersArea > 0 && isArea){
                    var ftArea = Math.round(metersArea * 10.76391 *100)/100;

                    var list = $('#landmark-edit-general > ul')[0];
                    var newList = document.createElement("UL");
                    newList.id = "AreaSize";

                    var newItem = document.createElement("LI");
                    if(isChecked("_cbShowAreaPlaceSizeMetric")){
                        newItem.innerHTML = "Area: " + metersArea.toFixed(2) + " m<sup>2</sup>";
                        newList.appendChild(newItem);
                    }

                    if(isChecked("_cbShowAreaPlaceSizeImperial")){
                        newItem = document.createElement("LI");
                        newItem.innerHTML = "Area: " + ftArea.toFixed(2) + " ft<sup>2</sup>";
                        newList.appendChild(newItem);
                    }
                    if(metersArea < 500){
                        newItem = document.createElement("LI");
                        newItem.innerHTML = "<span style='color:red; font-weight:bold;'>Places smaller than 500 m<sup>2</sup>/5382 ft<sup>2</sup> will not show in the client</span>";
                        newList.appendChild(newItem);
                    }
                    if(list.before != null)
                       list.before(newList);
                    else{
                        var parent = $('#landmark-edit-general > ul')[0].parentNode;
                        parent.insertBefore(newList,$('#landmark-edit-general > ul')[0]);
                    }

                    $('#AreaSize').addClass("list-unstyled");
                    $('#AreaSize').addClass("additional-attributes");
                }
            }
        }
    }

    function loadSettings() {
        var loadedSettings = $.parseJSON(localStorage.getItem("WMEPIE_Settings"));
        var defaultSettings = {
            ShowAreaPlaceSize: false,
            ShowAreaPlaceSizeImperial: false,
            ShowAreaPlaceSizeMetric: false,
            ShowLockButtonsRPP: true,
            NewPlacesList: W.Config.venues.categories.clone(),
            EditRPPAfterCreated: false,
            UseStreetFromClosestSeg: false,
            UseCityFromClosestSeg: false,
            ShowPlaceLocatorCrosshair: false,
            PlaceZoom: 6,
            DefaultLockLevel: 0
        };
        settings = loadedSettings ? loadedSettings : defaultSettings;
        for (var prop in defaultSettings) {
            if (!settings.hasOwnProperty(prop))
                settings[prop] = defaultSettings[prop];
        }

        if(settings.ShowAreaPlaceSizeImperial === false && settings.ShowAreaPlaceSizeMetric === false)
            if(Waze.prefs.attributes.isImperial)
                settings.ShowAreaPlaceSizeImperial = true;
            else
                settings.ShowAreaPlaceSizeMetric = true;
    }

     function saveSettings() {
        if (localStorage) {
            var localsettings = {
                ShowAreaPlaceSize: settings.ShowAreaPlaceSize,
                ShowAreaPlaceSizeImperial: settings.ShowAreaPlaceSizeImperial,
                ShowAreaPlaceSizeMetric: settings.ShowAreaPlaceSizeMetric,
                ShowLockButtonsRPP: settings.ShowLockButtonsRPP,
                NewPlacesList: settings.NewPlacesList,
                EditRPPAfterCreated: settings.EditRPPAfterCreated,
                UseStreetFromClosestSeg: settings.UseStreetFromClosestSeg,
                UseCityFromClosestSeg: settings.UseCityFromClosestSeg,
                ShowPlaceLocatorCrosshair: settings.ShowPlaceLocatorCrosshair,
                PlaceZoom: settings.PlaceZoom,
                DefaultLockLevel: settings.DefaultLockLevel
            };

            localStorage.setItem("WMEPIE_Settings", JSON.stringify(localsettings));
        }
    }

    //Using the same display for lock buttons as ClickSaver (with permission from MapoMatic) - thanks MoM!
    function addLockButtons() {
        if(W.selectionManager.selectedItems.length > 0){
            var item = W.selectionManager.selectedItems[0];
            var isRPP = (item.model.type === "venue" && item.model.attributes.residential === true);

            if(isRPP){
                var attr = item.model.attributes;
                var autoRank = attr.rank;
                var manualRank = attr.lockRank;
                var firstManualRank = manualRank;
                var userRank = WazeWrap.User.Rank() - 1;
                var maxAutoRank = autoRank;
                var disabled = false;

                var $div = $('#pieRPPLockButtonsContainer');
                $div.remove();
                $div = $('<div>',{id:'pieRPPLockButtonsContainer',style:'margin-bottom:5px;'});
                $div.append('<label class="control-label">Lock</label>');
                var btnInfos = [];

                for(var iBtn=0;iBtn<=6;iBtn++){btnInfos.push({r:iBtn,val:iBtn});}
                btnInfos.forEach(function(btnInfo){
                    console.log(typeof manualRank);
                    console.log(typeof btnInfo.val);
                    var selected = (btnInfo.val == manualRank);
                    disabled = userRank < btnInfo.val;
                    if (btnInfo.val !== 6) {
                        $div.append(
                            $('<div>', {
                                class:'btn btn-lh' + (selected ? ' btn-lh-selected':'') + (btnInfo.r < 6 & (userRank < btnInfo.r || disabled) ? ' disabled' : '')
                            })
                            .text(btnInfo.hasOwnProperty('title') ? btnInfo.title : btnInfo.r + 1)
                            .data('val',btnInfo.hasOwnProperty('val') ? btnInfo.val : btnInfo.r + 1)
                            .hover(function() {})
                            .click(function() {
                                if((userRank >= $(this).data('val')) && (btnInfo.r < 6)) {
                                    W.model.actionManager.add(new UpdateObject(item.model,{lockRank:($(this).data('val'))}));
                                    addLockButtons();
                                }
                            })
                        );
                    }
                });
                $('#landmark-edit-general > div').after($div);
            }
        }
    }

    function injectCss() {
        var css =  [
            // Lock button formatting
            '.btn-lh {cursor:pointer;padding:1px 6px;height:22px;border:solid 1px #c1c1c1;margin-right:3px;}',
            '.btn.btn-lh.btn-lh-selected {background-color:#6999ae;color:white}',
            '.btn.btn-lh.btn-lh-selected:hover {color:white}',
            '.btn.btn-lh.disabled {color:#909090;background-color:#f7f7f7;}',
            '.btn.btn-lh.btn-lh-selected.disabled {color:white;background-color:#6999ae;}'
        ].join(' ');
        $('<style type="text/css">' + css + '</style>').appendTo('head');
    }

    function listPlaces(){
        var category = "";
        for(i=0; i<W.Config.venues.categories.length; i++){
            category = W.Config.venues.categories[i];
            console.log(category + " Main");
            var subCategories = W.Config.venues.subcategories[category];
            for(var j=0; j<subCategories.length;j++){
                console.log(subCategories[j]);
            }
        }
    }
})();