WME Place Interface Enhancements

Enhancements to various Place interfaces

2017-01-11 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         WME Place Interface Enhancements
// @namespace    https://greatest.deepsurf.us/users/30701-justins83-waze
// @version      0.4.3
// @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 placementMode = false;

    // 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"><input type="checkbox" id="_cbShowLockButtonsRPP" class="pieSettingsCheckbox" /><label for="_cbShowLockButtonsRPP">Show lock buttons for RPPs</label></div>',
            '<b>New Places</b></br>',
            '<div id="divEditRPPAfterCreated" class="controls-container"><input type="checkbox" id="_cbEditRPPAfterCreated" class="pieSettingsCheckbox"><label for="_cbEditRPPAfterCreated">Edit RPP address after created</label></div>',
            '<div id="divUseStreetFromClosestSeg" class="controls-container"><input type="checkbox" id="_cbUseStreetFromClosestSeg" class="pieSettingsCheckbox"><label for="_cbUseStreetFromClosestSeg">Use street name from closest segment</label></div>',
            '<div id="divUseCityFromClosestSeg" class="controls-container"><input type="checkbox" id="_cbUseCityFromClosestSeg" class="pieSettingsCheckbox"><label for="_cbUseCityFromClosestSeg">Use city name from closest segment</label></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");

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

        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 = "";
        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
                $(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>');
        }

        $('[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(){
        //First load settings
        loadSettings();
        //Second 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
            {
                $('#RPPOptionPlaceLockButtonsContainer').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);
            }
        });

        //Third 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);
        if(settings.ShowAreaPlaceSize){
            $('#_cbShowAreaPlaceSizeImperial')[0].disabled = false;
            $('#_cbShowAreaPlaceSizeMetric')[0].disabled = false;
            attachPlaceSizeHandlers();
        }

        W.selectionManager.events.register("selectionchanged", null, showPlaceLocatorCrosshairs);
        if(settings.ShowLockButtonsRPP)
            attachRPPLockButtonHandlers();

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

        //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();
    }

    function startPlacementMode(category, isPoint){
        $('#edit-buttons > div > div.toolbar-button.waze-icon-place.toolbar-submenu.toolbar-group.toolbar-group-venues.ItemInactive').removeClass("open");
        $("#map").on('mousemove', MouseMoveHandler);
        $("#map").on('click', function(){endPlacementMode(category, isPoint);});
        document.addEventListener('keyup', keyUpHandler, false);
    }

    function keyUpHandler(e){
         if (e.keyCode == 27)
             disablePlacementMode();
    }

    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();
        NewPlace.geometry = new OL.Geometry.Point(pos.lon, pos.lat);
        NewPlace.attributes.categories.push(category);
        if(category === "RESIDENCE_HOME"){
            NewPlace._originalResidential = true;
            NewPlace.attributes.residential = true;
        }

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

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

        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);

        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 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(){
        $('#RPPOptionPlaceLockButtonsContainer').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 showPlaceLocatorCrosshairs(){
        if(W.selectionManager.selectedItems.length > 0){
            if(W.selectionManager.selectedItems[0].model.type === "venue"){
                var panelWidth = $('#user-info > div > div').width();
                var $crosshairs = $('<div style="position:absolute; left:' + (panelWidth - 20) + 'px;" id="pieCrosshairs"><i class="fa fa-crosshairs fa-lg" aria-hidden="true"></i></div>');
                console.log($crosshairs.html());
                $('.tab-content').prepend($crosshairs);
            }
        }
        else
            $('#pieCrosshairs').remove();
    }

    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.append(newItem);
                    }

                    if(isChecked("_cbShowAreaPlaceSizeImperial")){
                        newItem = document.createElement("LI");
                        newItem.innerHTML = "Area: " + ftArea.toFixed(2) + " ft<sup>2</sup>";
                        newList.append(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.append(newItem);
                    }
                    list.before(newList);

                    $('#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
        };
        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
            };

            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 = $('#RPPOptionPlaceLockButtonsContainer');
                $div.remove();
                $div = $('<div>',{id:'RPPOptionPlaceLockButtonsContainer',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){
                    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 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]);
            }
        }
    }
})();