Dependency("municware.turmehoi.Address", "municware.lang.Bean");

municware.turmehoi.Address = {};
            
municware.turmehoi.Address.create = function(initValues) {
    // TODO: Make address immutable!
    var address = municware.lang.Bean.create();
    address.addProperty("name"); // string
    address.addProperty("street"); // string
    address.addProperty("city"); // string
    address.addProperty("state"); // string
    address.toGoogleAddress = function() {
        var gAddr = (address.getStreet() != null && address.getStreet() != "" ? address.getStreet() : "") + 
            (address.getCity() != null && address.getCity() != "" ? ", " + address.getCity() : "") +
            (address.getState() != null && address.getState() != "" ? ", " + address.getState() : "");
        log.warn(gAddr);
        return gAddr;
    };
    address.toString = function() {
        return (address.getName() && address.getName() != "" ? address.getName() : 
                                (address.getStreet() && address.getStreet() != "" ? address.getStreet() : 
                                (address.getCity() && address.getCity() != "" ? address.getCity() : 
                                (address.getState() && address.getState() != "" ? address.getState() : ""))))
    };
    address.setInitialValues(initValues);
    return address;
};

log.debug("Loaded bean municware.turmehoi.Address");
Dependency("municware.turmehoi.AddressBook", "municware.lang.Bean");
Dependency("municware.turmehoi.AddressBook", "municware.widget.List");
Dependency("municware.turmehoi.AddressBook", "municware.turmehoi.Address");

municware.turmehoi.AddressBook = {};

municware.turmehoi.AddressBook.create = function(initValues) {
    var addressBook = municware.widget.List.createModel();
    addressBook.setInitialValues(initValues);
    var that = addressBook;
    // TODO: Points from address book could be loaded asynchronously!
    addressBook.loadFromString = function(def) {
        var lines = def.split("\n");

        for (var i = 2; i < lines.length; i += 5) {
            var address = municware.turmehoi.Address.create({
                name: lines[i],
                street: lines[i+1],
                city: lines[i+2],
                state: lines[i+3]
            });
            that.addItem(address);
        }
    };
    
    return addressBook;
};

log.debug("Loaded bean municware.turmehoi.AddressBook");
Dependency("municware.turmehoi.Waypoint", "municware.lang.Bean");

municware.turmehoi.Waypoint = {};

municware.turmehoi.Waypoint.createFromAddress = function(address) {
    return municware.turmehoi.Waypoint.create({
        address: address
    });
}

municware.turmehoi.Waypoint.create = function(initValues) {
    var wp = municware.lang.Bean.create();
    wp.addProperty("address"); // address
    wp.addProperty("arrivalTime"); // string
    wp.addProperty("arrivalDistance"); // string
    wp.addProperty("point"); // GLatLng
    wp.addIndexedProperty("overlays", "overlay"); // map overlays bound to wp
    /* wp.updatePoint = function() {
        var address = wp.getAddress();
        var gAddress = address.getStreet() +
            (address.getCity() != null && address.getCity() != "" ? ", " + address.getCity() : "") +
            (address.getState() != null && address.getState() != "" ? ", " + address.getState() : "");

        municware.turmehoi.geocoder.getLatLng(
            gAddress, // The search string 
            function(point) {
                wp.setPoint(point);
            }
        );
    };
    address.addDeepListener("address", function(src, event) {
        if (event.property == "name" || 
            event.property == "street" || 
            event.property == "city" || 
            event.property == "state") {
            wp.updatePoint();
        }
    }, function(src, event) {
        wp.updatePoint();
    }); */
    wp.setInitialValues({overlays: []});
    wp.setInitialValues(initValues);
    // address.updatePoint();
    return wp;
};

log.debug("Loaded bean municware.turmehoi.Waypoint");
Dependency("municware.turmehoi.Route", "municware.lang.Bean");

// TODO: Is this JS obsolete?

municware.turmehoi.Route = {};

municware.turmehoi.Route.create = function(initValues) {
    /* return new municware.lang.Bean([ 
            {property: "waypoints", type: "object", singularProperty: "waypoint", indexed: true, defaultValue: []}
            ], initValues); */
    var route = municware.lang.Bean.create(); 
    route.addIndexedProperty("waypoints", "waypoint");
    return route;   
};

log.debug("Loaded bean municware.turmehoi.Route");
/**
 * A form widget that lets the user create a new waypoint.
 *
 * Model specification: an address.
 */
 Dependency("municware.turmehoi.NewAddressPane", "municware.widget.Widget");
 Dependency("municware.turmehoi.NewAddressPane", "municware.widget.TextField");
 Dependency("municware.turmehoi.NewAddressPane", "municware.turmehoi.Address");

municware.turmehoi.NewAddressPane = Class.create(municware.widget.Widget, {
    
    initialize: function($super, element) {
        log.debug("Creating municware.turmehoi.NewAddressPane '" + element + "'");
        $super(element, "NewAddressPane");
        
        // Remove everything
        // this.element.innerHTML = "";
        var that = this;
        
        // Define a "private" variable space
        this._ = this._private["municware.turmehoi.NewAddressPane"] = {};
        
        // Initialize input elements
        this._.nameTextField = new municware.widget.TextField("create");
        this._.nameTextField.setModel(municware.widget.TextField.createModel({
            shortDesc: "Name",
            text: ""
        }));
        this._.streetTextField = new municware.widget.TextField("create");
        this._.streetTextField.setModel(municware.widget.TextField.createModel({
            shortDesc: "Street",
            text: ""
        }));
        this._.cityTextField = new municware.widget.TextField("create");
        this._.cityTextField.setModel(municware.widget.TextField.createModel({
            shortDesc: "City",
            text: ""
        }));
        this._.stateTextField = new municware.widget.TextField("create");
        this._.stateTextField.setModel(municware.widget.TextField.createModel({
            shortDesc: "State",
            text: ""
        }));
        
        this._. updatingModel = false;
        
        // Add input elements to container
        this.element.appendChild(this._.nameTextField.element);
        this.element.appendChild(this._.streetTextField.element);
        this.element.appendChild(this._.cityTextField.element);
        this.element.appendChild(this._.stateTextField.element);
        
        // Bind single input models to the Address
        this._.nameTextField.getModel().addListener("propertyChange", function() {
            that._.updatingModel = true;
            that.getModel().setName(that._.nameTextField.getModel().getText());
            that._.updatingModel = false;
        });
        this._.streetTextField.getModel().addListener("propertyChange", function() {
            that._.updatingModel = true;
            that.getModel().setStreet(that._.streetTextField.getModel().getText());
            that._.updatingModel = false;
        });
        this._.cityTextField.getModel().addListener("propertyChange", function() {
            that._.updatingModel = true;
            that.getModel().setCity(that._.cityTextField.getModel().getText());
            that._.updatingModel = false;
        });
        this._.stateTextField.getModel().addListener("propertyChange", function() {
            that._.updatingModel = true;
            that.getModel().setState(that._.stateTextField.getModel().getText());
            that._.updatingModel = false;
        });
        
        this.setModel(municware.turmehoi.Address.create());
    },
    
    reset: function() {
        this.setModel(municware.turmehoi.Address.create());
    },

    modelReset: function(oldModel, newModel) {
        if (newModel == null) {
            _.nameTextField.getModel().setText("");
            _.streetTextField.getModel().setText("");
            _.cityTextField.getModel().setText("");
            _.stateTextField.getModel().setText("");
        } else {
            // Update all properties
            this.modelChange(newModel, null);
        }
    },
    
    modelChange: function(model, event) {
        if (this._.updatingModel) {
            return;
        }
        
        var updateAll = !event;
        
        if (updateAll || event.property == "name") {
            this._.nameTextField.getModel().setText(model.getName());
        }
        
        if (updateAll || event.property == "street") {
            this._.streetTextField.getModel().setText(model.getStreet());
        }
        
        if (updateAll || event.property == "city") {
            this._.cityTextField.getModel().setText(model.getCity());
        }
        
        if (updateAll || event.property == "state") {
            this._.stateTextField.getModel().setText(model.getState());
        }
    },
    
    unload: function() {
        this._.inputElement.onclick = null;
    }
    
});

log.debug("Loaded class municware.turmehoi.NewAddressPane");
/**
 * A form widget that lets the user select a waypoint from an address book.
 *
 * Model specification: an address.
 */
 Dependency("municware.turmehoi.SelectAddressPane", "municware.widget.Widget");
 Dependency("municware.turmehoi.SelectAddressPane", "municware.widget.TextField");
 Dependency("municware.turmehoi.SelectAddressPane", "municware.widget.ComboBox");
 Dependency("municware.turmehoi.SelectAddressPane", "municware.turmehoi.Address");
 Dependency("municware.turmehoi.SelectAddressPane", "municware.turmehoi.AddressBook");

// TODO: remove duplicate code
municware.turmehoi.geocoder = municware.turmehoi.geocoder ? municware.turmehoi.geocoder : new GClientGeocoder();

municware.turmehoi.SelectAddressPane = Class.create(municware.widget.Widget, {
    
    initialize: function($super, element) {
        log.debug("Creating municware.turmehoi.SelectAddressPane '" + this + "'");
        $super(element, "SelectAddressPane");
        
        // Remove everything
        // this.element.innerHTML = "";
        var that = this;
        
        this.addProperty("pointCache"); // hash
        this.addProperty("addressBook"); // AddressBook
        
        // Define a "private" variable space
        this._ = this._private["municware.turmehoi.SelectAddressPane"] = {};
        
        this._.updatingModel = false;
        
        this._.importAddressBookTextField = new municware.widget.TextField("create", true);
        this._.importAddressBookTextField.setModel(municware.widget.TextField.createModel({
            shortDesc: "Import",
            longDesc: "Paste your address book here...",
            text:   "2008-04-10 Example\r\n" +
                    "\r\n" +
                    "Stuttgart Hbf\r\n" +
                    "Arnulf-Klett-Platz\r\n" +
                    "70173 Stuttgart\r\n" +
                    "Deutschland\r\n" +
                    "\r\n" +
                    "Stuttgart Wilhelmsplatz\r\n" +
                    "Wilhelmsplatz (Bad Cannstatt)\r\n" +
                    "Stuttgart\r\n" +
                    "Deutschland\r\n" +
                    "\r\n" +
                    "Stuttgart Pragsattel\r\n" +
                    "Pragsattel\r\n" +
                    "70191 Stuttgart\r\n" +
                    "Deutschland"
        }));
        
        this._.importAddressBookButton = new municware.widget.Button("create");
        this._.importAddressBookButton.setModel(municware.widget.Button.createModel({
            shortDesc: "Import",
            longDesc: "Import the pasted address book",
            action: function(buttonModel, context) {
                var addressBook = municware.turmehoi.AddressBook.create();
                addressBook.loadFromString(that._.importAddressBookTextField.getModel().getText());
                that.setAddressBook(addressBook);
            }
        }));
        
        this._.addressComboBox = new municware.widget.ComboBox("create");
        this._.addressComboBox.setRenderer(function(address) {
            return address.getName();
        });
        
        var importToolBar = document.createElement("div");
        importToolBar.addClassName("ToolBar");
        importToolBar.appendChild(this._.importAddressBookButton.element);
        
        this.element.appendChild(this._.importAddressBookTextField.element);
        this.element.appendChild(importToolBar);
        this.element.appendChild(document.createElement("br"));  
        // Add input elements to container
        this.element.appendChild(this._.addressComboBox.element);
        
        // Bind address book to combo box
        this.addListener("propertyChange", function(src, event) {
            if (event.property == "addressBook") {
                that._.addressComboBox.setModel(event.newValue);
            }
        });
        
        // Install a sample address book as default
        var sampleAddressBook = municware.turmehoi.AddressBook.create();
        sampleAddressBook.loadFromString(this._.importAddressBookTextField.getModel().getText());
        that.setAddressBook(sampleAddressBook);
        
        var itemModel = this._.addressComboBox.getModel();
        var selectionModel = this._.addressComboBox.getSelectionModel();
        
        // Bind single input models to the Address
        selectionModel.addListener("propertyChange", function() {
            that._.updatingModel = true;
            var selectedAddress = selectionModel.getSelectionAt(0);
            var pointCache = that.getPointCache();
            if (selectedAddress && pointCache) {
                // Make an attempt to load the GPS location of the specified
                // point into the cache.
                var gAddress = selectedAddress.toGoogleAddress();
                if (!pointCache[gAddress]) {
                    municware.turmehoi.geocoder .getLatLng(
                        gAddress, // The search string 
                        function(point) {
                            pointCache[gAddress] = point;
                        }
                    );
                }
            }
            // The selection corresponds to the model of this widget.
            that.setModel(selectedAddress);
            that._.updatingModel = false;
        });
        
        if (itemModel.getItemCount() > 0) {
            selectionModel.addSelection(itemModel.getItemAt(0));
        }
    },
    
    reset: function() {
        // this.setModel(municware.turmehoi.Address.create());
    },
    
    modelReset: function(oldModel, newModel) {
        if (newModel == null) {
            // Do nothing
        } else {
            // Update all properties
            this.modelChange(newModel, null);
        }
    },
    
    modelChange: function(model, event) {
    },
    
    unload: function() {
    }
    

});

log.debug("Loaded class municware.turmehoi.SelectAddressPane");
