<commit_before>/**
 * This file holds methods and classes used for district handling
 * like managing polygons and districts themselves
 */

/**
 * Converts a polygon to a json representation
 * @return string jsonrepresentation of a polygon path
 * (Extending polygons)
 */
google.maps.Polygon.prototype.toJson = function() {
    return JSON.stringify(this.getPath().b);
}

/**
 * Extensions checks if this is a new entry or if the entry was already
 * assigned to a district
 * @return {Boolean} Wether the polygon has been saved for a district or not
 */
google.maps.Polygon.prototype.isNew = function() {
    var id = this.get('id');
    return id == undefined;
}

/**
 * Converts a json ecnoded polygon path back to a polygon (Extending strings)
 * @return {google.maps.Polygon} Converts a json string to a polygon
 */
String.prototype.toPolygon = function() {
    var coords = new Array();

    try {
        // Try to parse the representation
        var parsed = JSON.parse(this);
        // And loop through the values and create points for the polygon
        $.each(parsed, function(i, curr) {
            coords.push(new google.maps.LatLng(curr.Xa, curr.Ya));
        });
    } catch (err) {
        // On failure reset it
        coords = new Array();
    }

    // Finally return the polygon
    return new google.maps.Polygon({
        paths: coords,
        fillOpacity: 0.05
      });
}

function Districts(map) {
    var self = this;
    this.map = map;

    // Adds a ditrict from storage to the map and already assigns all required data
    this.add = function(district) {
        // verify the data structure a bit
        if (district == undefined) return false;
        if (district.polygon == undefined || district.id == undefined || district.name == undefined) return false;

        // Create the polygon and add it to the map
        var poly = district.polygon.toPolygon();
        poly.set('id',   district.id);
        poly.set('name', district.name);

        // Bind event handlers
        google.maps.event.addListener(poly, 'mouseover', function() {
            console.log("Name: "+ poly.get("name"));
            console.log("Id: "+ poly.get("id"));
        });

        // On click select for editing (If currently no other one is being editied)
        google.maps.event.addListener(poly, 'click', function() {
              self.edit(poly);
        });

        poly.setMap(self.map.map);
    };

    this.editing        = false;
    this.editingPolygon = null;
    this.originalPath   = null;

    // Will start editing a polygon
    // Editing may be "editing of a new district" or "editing of an existant district"
    // this is based on the data stored for the given polygon
    this.edit = function(polygon) {
        // If we are already editing something or the provided polygon is invalid, stop right here
        if (polygon == undefined) return false;
        if (self.isEditing) return false;

        self.isEditing      = true;
        self.editingPolygon = polygon;
        polygon.setEditable(true);

        // Is this a new one or an existing polygon...
        if (!polygon.isNew()) {
            // Exisitng entry
            // Store current path of the polygon (In case we wish to reset it later on)
            // Yes this is done by a conversion in between since else the points would be handled
            // by reference which means that they hold all translations made. This way we get a clean
            // copy.
            self.originalPath = polygon.toJson().toPolygon().getPath();

            // Load the data to show
            $.get('district/'+ polygon.get('id'), function(data) {
                $('#district_form input[name=name]').val(data.name);
                $('#district_form textarea[name=description]').val(data.description);
                $('#forms').show();
            }, 'json')
        } else {
            // A New one, just show the forms
            $('#district_form input[name=name]').val("");
            $('#district_form textarea[name=description]').val("");
            $('#forms').show();
        }
    };

    // Cancels the editing process
    // In case a new district was currently being created the polygon will be removed from the map.
    // Also the forms will be hidden and any changes made just be reset
    this.cancel = function() {
        if (!self.isEditing) return false;

        if (self.editingPolygon) {
            // Reset editing mode
            self.editingPolygon.setEditable(false);
            // If this is a new polygon, also remove it from the map
            if (self.editingPolygon.isNew()) {
                self.editingPolygon.setMap(null);
            } else {
                // If not, restore the path
                if (self.originalPath)
                    self.editingPolygon.setPath(self.originalPath);
            }
        }

        self.isEditing      = false;
        self.editingPolygon = null;
        self.originalPath   = null;
        $('#forms').hide();
    };

    // Bind to save event of the editing form, so we can submit the data
    $('#district_form').on('submit', function() {
        // Just stop here is we are not editing anything
        if (!self.isEditing || !self.editingPolygon) return false;

        // Stop editing mode
        self.editingPolygon.setEditable(false);

        // Serialize the form data
        var data = {};
        jQuery.map($(this).serializeArray(), function(n, i) {
            data[n['name']] = n['value'];
        });

        // For now this is fix...
        data.region_id = 1;

        // And serialize the polygon
        data.polygon   = self.editingPolygon.toJson();

        // Based on wether this is an existant district or a new one
        // the url as well as the parameters will change
        var type = 'POST';
        var url  = 'district/add/';
        if (!self.editingPolygon.isNew()) {
            // Not a new one: Editing
            type             = "PUT";
            url              = 'district/edit/';
            data.district_id = self.editingPolygon.get('id');
        }

        $.ajax({
                type:     type,
                url:      url,
                data:     data,
                dataType: "json"
            }).done(function(data) {
                if (data.ok == "ok") {
                    // Was ok, was saved, we are done
                    self.isEditing      = false;

                    // Update the entity infos for the polygon
                    self.editingPolygon.set('id',   data.entity.id);
                    self.editingPolygon.set('name', data.entity.name);

                    self.editingPolygon = null;
                    self.originalPath   = null;
                    $('#forms').hide();<commit_msg>District highlighting<commit_after>/**
 * This file holds methods and classes used for district handling
 * like managing polygons and districts themselves
 */

/**
 * Converts a polygon to a json representation
 * @return string jsonrepresentation of a polygon path
 * (Extending polygons)
 */
google.maps.Polygon.prototype.toJson = function() {
    return JSON.stringify(this.getPath().b);
}

/**
 * Extensions checks if this is a new entry or if the entry was already
 * assigned to a district
 * @return {Boolean} Wether the polygon has been saved for a district or not
 */
google.maps.Polygon.prototype.isNew = function() {
    var id = this.get('id');
    return id == undefined;
}

/**
 * Converts a json ecnoded polygon path back to a polygon (Extending strings)
 * @return {google.maps.Polygon} Converts a json string to a polygon
 */
String.prototype.toPolygon = function() {
    var coords = new Array();

    try {
        // Try to parse the representation
        var parsed = JSON.parse(this);
        // And loop through the values and create points for the polygon
        $.each(parsed, function(i, curr) {
            coords.push(new google.maps.LatLng(curr.Xa, curr.Ya));
        });
    } catch (err) {
        // On failure reset it
        coords = new Array();
    }

    // Finally return the polygon
    return new google.maps.Polygon({
        paths:        coords
      });
}

function Districts(map) {
    var self = this;
    this.map = map;

    // Function handles "Adding polygons to the map"
    // This might be done with existing or new polygons likewise
    // exisiting polygons just retrieve event resets
    // Also the styles of the polygons will be applied here
    this.addPolygon = function(polygon) {
        // Clear all listeners beforehand
        google.maps.event.clearInstanceListeners(polygon);

        // Bind event handlers
        google.maps.event.addListener(polygon, 'mouseover', function() {
            console.log("Name: "+ polygon.get("name"));
            console.log("Id: "+ polygon.get("id"));

            if (!self.isEditing)
                polygon.set('fillOpacity', 0.25);
        });

        google.maps.event.addListener(polygon, 'mouseout', function() {
            if (!self.isEditing)
                polygon.set('fillOpacity', 0.05);
        });

        // On click select for editing (If currently no other one is being editied)
        google.maps.event.addListener(polygon, 'click', function() {
              self.edit(polygon);
        });

        // Apply polygon styles
        polygon.set('strokeColor',   '#fff');
        polygon.set('strokeWeight',  2);
        polygon.set('strokeOpacity', 0.25);
        polygon.set('fillColor',     '#000');
        polygon.set('fillOpacity',   0.05);

        polygon.setMap(self.map.map);
    };

    // Adds a ditrict from storage to the map and already assigns all required data
    this.add = function(district) {
        // verify the data structure a bit
        if (district == undefined) return false;
        if (district.polygon == undefined || district.id == undefined || district.name == undefined) return false;

        // Create the polygon and add it to the map
        var polygon = district.polygon.toPolygon();
        polygon.set('id',   district.id);
        polygon.set('name', district.name);

        self.addPolygon(polygon);
    };

    this.editing        = false;
    this.editingPolygon = null;
    this.originalPath   = null;

    // Will start editing a polygon
    // Editing may be "editing of a new district" or "editing of an existant district"
    // this is based on the data stored for the given polygon
    this.edit = function(polygon) {
        // If we are already editing something or the provided polygon is invalid, stop right here
        if (polygon == undefined) return false;
        if (self.isEditing) return false;

        self.isEditing      = true;
        self.editingPolygon = polygon;
        polygon.setEditable(true);

        // Is this a new one or an existing polygon...
        if (!polygon.isNew()) {
            // Exisitng entry
            // Store current path of the polygon (In case we wish to reset it later on)
            // Yes this is done by a conversion in between since else the points would be handled
            // by reference which means that they hold all translations made. This way we get a clean
            // copy.
            self.originalPath = polygon.toJson().toPolygon().getPath();

            // Load the data to show
            $.get('district/'+ polygon.get('id'), function(data) {
                $('#district_form input[name=name]').val(data.name);
                $('#district_form textarea[name=description]').val(data.description);
                $('#forms').show();
            }, 'json')
        } else {
            // A New one, just show the forms
            $('#district_form input[name=name]').val("");
            $('#district_form textarea[name=description]').val("");
            $('#forms').show();
        }
    };

    // Cancels the editing process
    // In case a new district was currently being created the polygon will be removed from the map.
    // Also the forms will be hidden and any changes made just be reset
    this.cancel = function() {
        if (!self.isEditing) return false;

        if (self.editingPolygon) {
            // Reset editing mode
            self.editingPolygon.setEditable(false);
            // If this is a new polygon, also remove it from the map
            if (self.editingPolygon.isNew()) {
                self.editingPolygon.setMap(null);
            } else {
                // If not, restore the path
                if (self.originalPath)
                    self.editingPolygon.setPath(self.originalPath);
                // And readd the polygon
                self.addPolygon(self.editingPolygon);
            }
        }

        self.isEditing      = false;
        self.editingPolygon = null;
        self.originalPath   = null;
        $('#forms').hide();
    };

    // Bind to save event of the editing form, so we can submit the data
    $('#district_form').on('submit', function() {
        // Just stop here is we are not editing anything
        if (!self.isEditing || !self.editingPolygon) return false;

        // Stop editing mode
        self.editingPolygon.setEditable(false);

        // Serialize the form data
        var data = {};
        jQuery.map($(this).serializeArray(), function(n, i) {
            data[n['name']] = n['value'];
        });

        // For now this is fix...
        data.region_id = 1;

        // And serialize the polygon
        data.polygon   = self.editingPolygon.toJson();

        // Based on wether this is an existant district or a new one
        // the url as well as the parameters will change
        var type = 'POST';
        var url  = 'district/add/';
        if (!self.editingPolygon.isNew()) {
            // Not a new one: Editing
            type             = "PUT";
            url              = 'district/edit/';
            data.district_id = self.editingPolygon.get('id');
        }

        $.ajax({
                type:     type,
                url:      url,
                data:     data,
                dataType: "json"
            }).done(function(data) {
                if (data.ok == "ok") {
                    // Was ok, was saved, we are done
                    self.isEditing      = false;

                    // Update the entity infos for the polygon
                    self.editingPolygon.set('id',   data.entity.id);
                    self.editingPolygon.set('name', data.entity.name);
                    self.addPolygon(self.editingPolygon);

                    self.editingPolygon = null;
                    self.originalPath   = null;
                    $('#forms').hide();
{'fraction_non_alphanumeric': 0.11189907944084555, 'fraction_numerical': 0.001431980906921241, 'mean_word_length': 1.8622170179547228, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2616151', 'n_tokens_mistral': 4049, 'n_tokens_neox': 3875, 'n_words': 1281}