/*
    Mapa Inwestycji
    Copyright (C) 2006-2007 Jakub Labenski

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation version 3 of the License.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

function Shape()
{
    this.polylineList = [];
    this.deactivate();
}

Shape.prototype.remove = function(id) {
    for (var polyline in this.polylineList) {
        var newPoly = [];
        for (i in this.polylineList[polyline]) {
            check = this.polylineList[polyline][i];
            if (check != id) {
                newPoly.push(check);
            } else {
                log ("R: " + check);
            }
        }
        this.polylineList[polyline] = newPoly;
    }
    if (id == this.active) {
        this.deactivate();
    }
}

Shape.prototype.isActive = function() {
    return this.active != -1;
}

Shape.prototype.deactivate = function() {
    this.active = -1;
    this.activePolyLine = -1;
}

Shape.prototype.findAtEnds = function(id, start)
{ 
    for (var polyline in this.polylineList) {
        var poly = this.polylineList[polyline];
        if (poly.length > 0) {
            if (poly[poly.length - 1] == id) {
                if (start == true) {
                    poly.reverse();
                }
                return polyline;
            } else if (poly[0] == id) {
                if (start == false) {
                    poly.reverse();
                }
                return polyline;
            }
        }
    }
    return -1;
}

Shape.prototype.translate = function(ttable)
{ 
    for (var polyline in this.polylineList) {
        var poly = this.polylineList[polyline];
        for (var i in poly) {
            poly[i] = ttable[poly[i]];
        }
    }
    if (this.active != -1) {
        this.active = ttable[this.active];
    }
}

Shape.prototype.toString = function()
{
    var txt = "";
    for (var polyline in this.polylineList) {
        var poly = this.polylineList[polyline];
        if (poly.length > 0) {
            txt += "(";
            for (i in poly) {
                txt += poly[i] + ",";
            }
            txt += "),";
        }
    }
    return txt;
}

Shape.prototype.add = function(id) {

    if (this.activePolyLine == -1) {
        if (this.active == -1) {
            log("New polyline (0)");
            this.activePolyLine = this.polylineList.length;
            this.polylineList.push([]);
        } else {
            this.activePolyLine = this.findAtEnds(this.active, false);
            if (this.activePolyLine == -1) {
                log("New polyline (1)");
                this.activePolyLine = this.polylineList.length;
                this.polylineList.push([ this.active ]);
            }
        }
    } else if (this.active == -1) {
        alert("this.activePolyLine != 0) && (this.active == -1))");
    }

    log("Adding point: " + id);
    var reused = this.findAtEnds(id, true);
    if (reused != -1 && reused != this.activePolyLine) {
        log("Reusing");
        this.polylineList[this.activePolyLine] = 
        this.polylineList[this.activePolyLine].concat(
                this.polylineList[reused]);
        this.polylineList[reused] = [];
        this.activePolyLine = -1;
        this.active = id;
    } else {
        this.polylineList[this.activePolyLine].push(id);
        this.active = id;
    }
}

Shape.prototype.addList = function(list) {
    this.polylineList.push(list);
}

function Markers()
{
}

Markers.prototype.markers = [];

Markers.prototype.compact = function()
{
    var newMarkers = [];
    var ttable = []
    for (var i in this.markers) {
        if (this.markers[i] != 0) {
            ttable.push(newMarkers.length);
            this.markers[i].id = newMarkers.length;
            newMarkers.push(this.markers[i]);
        } else {
            ttable.push(-1);
        }
    }
    this.markers = newMarkers;
    return ttable;
}

Markers.prototype.deactivate = function(id)
{
    if (id != -1) {
        m = this.markers[id];
        return this.readd(m, -1);
    }
    return -1;
}

Markers.prototype.activate = function(id)
{
    if (id != -1) {
        m = this.markers[id];
        return this.readd(m, activeIcon);
    }
    return -1;
}

Markers.prototype.readd = function(m, icon)
{
   var newM = this.newMarker(m.getPoint(), icon, m.visible, m.id);

    this.markers[m.id] = newM;
    map.removeOverlay(m);
    map.addOverlay(newM);
    return newM
}

Markers.prototype.newMarker = function(point, icon, visible, id)
{
    if (icon == -1) {
        if (visible) {
            icon = visibleIcon;
        } else {
            icon = grayIcon;
        }
    }
    
    var marker = new GMarker(point, { icon: icon, draggable: true});
    GEvent.addListener(marker, "dragend", function() { editor.print(); });
   
    GEvent.addListener(marker, "dblclick", function() { 
            if (this.visible) { 
                this.visible = 0; 
            } else { 
                this.visible = 1; 
            }; 
            //checkReq();
            if (drawMode == 0 || editor.shape.active != this.id) {
                map.closeInfoWindow();
                editor.markers.readd(this, -1);
            }
        });

    marker.id = id;
    marker.visible = visible;

    return marker;
}

Markers.prototype.add = function(point, visible, icon)
{
    var marker = this.newMarker(point, icon, visible, this.markers.length);
    
    map.addOverlay(marker);
    this.markers.push(marker);

    return marker.id
}

Markers.prototype.remove = function(marker)
{
    this.markers[marker.id] = 0;
}

Markers.prototype.toString = function()
{
    var txt = "";
    for (var i in this.markers) {
        txt += "(" + this.markers[i].getPoint().lat() + ", " + this.markers[i].getPoint().lng()  + ", " + this.markers[i].visible + ")";
    }
    return txt;
}

Markers.prototype.getPoints = function(ids)
{
    var ret = [];
    for (id in ids) {
        ret.push(this.markers[ids[id]].getPoint());
    }
    return ret;
}

Markers.prototype.statusChanged = function()
{
    for (var marker in this.markers) {
        if (this.markers[marker].visible) {
            this.readd(this.markers[marker], -1);
        }
    }
}

function Editor()
{
}

Editor.prototype.shape = new Shape();
Editor.prototype.markers = new Markers();
Editor.prototype.shapeColor;
Editor.prototype.shapeOverlays = [];

Editor.prototype.clear = function()
{
    this.markers.markers = [];
    this.shape = new Shape();
    this.shapeOverlays = [];
    map.clearOverlays();
    //checkReq();
}
 
Editor.prototype.print = function()
{
    for (var i in this.shapeOverlays) {
        map.removeOverlay(this.shapeOverlays[i]);
    }
    this.shapeOverlays = [];

    for (var i in this.shape.polylineList) {
        var c = this.shape.polylineList[i];
        if (c.length > 1) {
            var points = this.markers.getPoints(c);
            var path;

            if (c[0] == c[c.length - 1]) {
                path = new GPolygon(points, this.shapeColor, 5, 0.66, this.shapeColor, 0.38);
            } else {
                path = new GPolyline(points, this.shapeColor, 5);
            }
            map.addOverlay(path);
            this.shapeOverlays.push(path);
        }
    }
}

Editor.prototype.add = function(point)
{
    if (this.shape.isActive()) {
        this.markers.deactivate(this.shape.active);
    }

    this.shape.add(this.markers.add(point, 0, activeIcon));
    //checkReq();
    this.print();
}
Editor.prototype.empty = function(point)
{
    return this.markers.markers.length == 0;
}

Editor.prototype.addVisible = function(point)
{
    this.shape.add(this.markers.add(point, 1, -1));
    //checkReq();
    this.print();
}
 
Editor.prototype.remove = function(marker)
{
    this.markers.remove(marker);
    this.shape.remove(marker.id);
    map.removeOverlay(marker);
    //checkReq();
    this.print();
}

Editor.prototype.reactivate = function(marker)
{
    this.markers.deactivate(this.shape.active);
    if (this.shape.active == marker.id) {
        this.shape.deactivate();
    } else {
        if (this.shape.isActive()) {
            this.shape.add(marker.id);
            this.print();
        }
        this.shape.active = this.markers.activate(marker.id).id;
    }
}
 
Editor.prototype.activate = function()
{
    this.markers.activate(this.shape.active);
}

Editor.prototype.deactivate = function()
{
    this.markers.deactivate(this.shape.active);
}
 
Editor.prototype.loadShape = function(txt)
{
    var list = [];
    nextList(txt, 0, list, nextList, nextList, nextNumber);

    if (list.length == 0) {
        map.setCenter(new GLatLng(0, 0), 1, G_NORMAL_MAP);
        return;
    }

    var bounds = new GLatLngBounds();

    for (var i in list[0][0]) {
        bounds.extend(new GLatLng(list[0][0][i][0], list[0][0][i][1]));
    }

    var zoom = map.getBoundsZoomLevel(bounds);
    map.setCenter(bounds.getCenter(), zoom); 

    for (var i in list[0][0]) {
        var enabled = 0;

        // To remove;
        if (list[0][0][i].length < 3 || list[0][0][i][2] == 1) {
            enabled = 1;
        }
        this.markers.add(new GLatLng(list[0][0][i][0], list[0][0][i][1]), enabled, -1);
    }

    for (var i in list[0][1]) {
        this.shape.addList(list[0][1][i]);
    }

    //checkReq();
    this.print(); 
}

Editor.prototype.anyVisible = function()
{
    for (var i in this.markers.markers) {
        if (this.markers.markers[i].visible) {
            return true;
        }
    }
    return false;
}

Editor.prototype.store = function() {
    var ttable = this.markers.compact();
    this.shape.translate(ttable);

    return "((" + this.markers.toString() + "), (" + this.shape.toString() + "))";
}

Editor.prototype.statusChanged = function()
{
    visibleIcon = getIcon(gb_type, gb_status);

    this.shapeColor = getShapeColor(gb_status);

    this.markers.statusChanged();

    this.print();
}

function EditorControl() {
}

EditorControl.prototype = new MiControl();

EditorControl.prototype.initialize = function(map) {
    var container = document.createElement("div");

    var drawButton = this.createButton_(container, lcDraw, 1);
    GEvent.addDomListener(drawButton, "click", function() {
        if (drawMode == 0) {
            editor.activate();
            drawMode = 1;
            setButtonState(deleteButton, deleteMode);
        } else {
            editor.deactivate();
            drawMode = 0;
            dissableButton(deleteButton);
        }
        setButtonState(drawButton, drawMode);
   });


    var deleteButton = this.createButton_(container, lcDelete, 0);
    GEvent.addDomListener(deleteButton, "click", function() {
        if (drawMode == 1) {    
            if (deleteMode == 0) {
                deleteMode = 1;
            } else {
                deleteMode = 0;
            }
            setButtonState(deleteButton, deleteMode);
        }
   });

    var clearButton = this.createButton_(container, lcClear, 1);
    GEvent.addDomListener(clearButton, "click", function() {
        editor.clear();
    });

    map.getContainer().appendChild(container);
    return container;
}

function checkReq()
{
    var ok = true;
    if (document.getElementById("name").value == "") {
        printInfo(lcNameIsRequired + ".");
        ok = false;
    }
    
    if (ok && document.getElementById("city").value == "") {
        printInfo(lcCityIsRequired + ".");
        ok = false;
    }
    
    if (ok && editor.anyVisible() == false) {
        printInfo(lcNonGrayIsRequired + ".");
        ok = false;
    }
    if (ok) {
        document.getElementById("add").disabled=false;
        if (document.getElementById("update")) {
            document.getElementById("update").disabled=false;
        }
        printInfo("");
    } else {
        document.getElementById("add").disabled=true;
        if (document.getElementById("update")) {
            document.getElementById("update").disabled=true;
        }
    }
}

function updateShapeInput() 
{
    var txt = editor.store();
    document.getElementById("shape").value = txt;
}

var textNode = 0;
function printInfo(txt)
{
    var infoDiv = document.getElementById("infoDiv");
    if (textNode) {
        infoDiv.removeChild(textNode);
    }
    textNode = infoDiv.appendChild(document.createTextNode(txt));
}

function typeChanged()
{
    editor.statusChanged();
}

function statusChanged()
{
    editor.statusChanged();
}

function loadEditor(zoom, coor1, coor2) {
    if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map"));
        map.addControl(new GSmallMapControl());
        map.addControl(new GMapTypeControl());
        map.addControl(new EditorControl());

        initIcons();
        inactiveIcon = grayIcon;
 
        GEvent.addListener(map, "click", function(marker, point) {
            if (drawMode == 0) {    
                if (marker && marker.visible) {
                    id = "";
                    if (document.getElementById("id")) {
                        id = document.getElementById("id").value;
                    }
                    status = gb_status;
                    name = quote(gb_name);
                    description = '';//quote(document.getElementById("description").value);

                    showInfoWindowHtml(marker, name, status, description, id);
                } else if (editor.empty()) {
                    editor.addVisible(point);
                }
            } else {
                if (point && deleteMode == 0) {
                    editor.add(point);
                } else if (marker) {
                    if (deleteMode == 0) {
                        editor.reactivate(marker);
                    } else {
                        editor.remove(marker);
                    }
                }
            }

        });
        load(map);
        editor.statusChanged();
        if (document.getElementById("shape").value.length > 0) {
            log(document.getElementById("shape").value);
            editor.loadShape(document.getElementById("shape").value);
        } else if (zoom>0) {
            map.setCenter(new GLatLng(coor1, coor2), zoom, G_NORMAL_MAP);
        } else {
            map.setCenter(new GLatLng(0, 0), 1, G_NORMAL_MAP);
        }
        //checkReq();
    }
}

var deleteMode = 0;
var drawMode = 0;
var editor = new Editor();
