var d = document;
var map;

var APIkeys = {
    cityofmelissacom: "ABQIAAAA8yXsrc06XvyA-rWZhcfHzRTrSGnAw_EeHtrwAUbhzsp29AZ5pRQFB9O34jAn_aZiDKL6X93PIGynSg",
    googlecom: "ABQIAAAA1XbMiDxx_BTCY2_FkPh06RRaGTYH6UMl8mADNa0YKuWNNa8VNxQEerTAUcfkyrr6OwBovxn7TDAH5Q"
};


//d.write('<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key='+ APIkeys.cityofmelissacom +'"><\/script>');
d.write('<script src="http://maps.google.com/maps/api/js?sensor=false"><\/script>');

function initMap(editable) {

    var editform;
    var iw = new google.maps.InfoWindow();

    if ("string" == typeof mapdata){
        if (editable){ d.XMLForm.mapdata.value = mapdata; }
        // migrate from v2 to v3
        mapdata = mapdata.replace(/GLatLng/g, "google.maps.LatLng");
        mapdata = eval("({"+mapdata+"})");
    }
    if ('undefined' == typeof mapdata.center || 'undefined' == typeof mapdata.zoom) {
        mapdata.center = new google.maps.LatLng(33.285946, -96.5727675); // Melissa, TX
        mapdata.zoom = 13;
    }
    if ('undefined' == typeof mapdata.markers){
        mapdata.markers = [];
    }

    // Make the map and set settings
    map = new google.maps.Map(d.getElementById("map_canvas"), {
        center: mapdata.center,
        zoom: mapdata.zoom,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        mapTypeControl: false
    });
    if (editable) {
        //map.enableGoogleBar();
        mapdata.origCenter = mapdata.center;
        mapdata.origZoom = mapdata.zoom;
    }

    // ----- Map Events ----- //
    google.maps.event.addListener(map, "dragend", function(){
        mapdata.center = map.getCenter();
    });
    google.maps.event.addListener(map, "zoom_changed", function(){
        mapdata.zoom = map.getZoom();
    });
    google.maps.event.addListener(map, "click", function(){
        if (editable && editform.m && editform.m.editing) editform.saveIt();
        iw.close();
    });

    // Create and set up map controls for editing
    if (editable) {
        var ctlBox = d.getElementById("map_controls");
        var ctl;

        // Add Marker button
        ctlBox.appendChild( ctl = Element("div", "Add Marker", { "class":"button" }) );
        ctl.onclick = function(){
            mapdata.markers.push( newMark({ loc: map.getCenter(), title: prompt("Title?", "New Marker"), desc: "(No description.)" }, mapdata.markers.length) );
            return false;
        };

        // Reset button
        ctlBox.appendChild( ctl = Element("div", "Reset Zoom/Center", { "class":"button" }) );
        ctl.onclick = function(){
            map.setZoom(mapdata.origZoom);
            mapdata.zoom = mapdata.origZoom;
            map.panTo(mapdata.origCenter);
            mapdata.center = mapdata.origCenter;
        };

        // DEBUG button - TODO: remove later
        ctlBox.appendChild( ctl = Element("div", "Save Map Data", { "class":"button" }) );
        ctl.onclick = function(){
            d.XMLForm.mapdata.value = serialize();
            alert("Data stored. Save this page to make it permanent.");
            return false;
        };

        ctlBox.appendChild( Element("br", null, { "clear":"all" }) );

        // ----- tinyMCE initialization ----- //
        var tinyOpts = {
            mode:"none",
            theme:"advanced",
            plugins:"contextmenu,inlinepopups,paste,table",
            theme_advanced_toolbar_location:"top",
            theme_advanced_toolbar_align:"left",
            theme_advanced_statusbar_location:"bottom",
            theme_advanced_resizing:true,
            theme_advanced_resize_horizontal:true,
            theme_advanced_resizing_use_cookie:false,
            dialog_type:"modal",
            paste_auto_cleanup_on_paste:true,
            paste_retain_images:true,
            paste_retain_bookmarks:true,
            paste_remove_styles:true,
            convert_fonts_to_spans:true,
            inline_styles:false,
            extended_valid_elements:"+center,h1[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|align<center?justify?left?right],h2[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|align<center?justify?left?right],h3[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|align<center?justify?left?right],h4[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|align<center?justify?left?right],h5[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|align<center?justify?left?right],h6[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|align<center?justify?left?right],+a[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|rel|rev|charset|accesskey|type|href|target|template|module|recordid|file|other],+div[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|align<center?justify?left?right,iframe[id|name|class|style|title|longdesc|src|allowtransparency|frameborder|scrolling|height|width|hspace|vspace|marginheight|marginwidth|align<bottom?middle?left?right?top],form[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|action|accept|accept-charset|enctype|method|onsubmit|onreset|target],img[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|usemap|src|border|alt|hspace|vspace|width|height|align|name],map[id|name],area[shape|alt|coords|href|target],input[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|accept|alt|checked|disabled|maxlength|readonly|size|src|type|value|accesskey|previousname|texttype|required],+textarea[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|cols|rows|disabled|readonly|wrap|accesskey|previousname|texttype|maxlength|required],+select[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|disabled|multiple|size|accesskey|previousname|required],+option[id|class|style|title|longdesc|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|name|tabindex|onfocus|onblur|disabled|label|selected|value]",
            scrolling:"yes",
            theme_advanced_styles:"",
            theme_advanced_blockformats:"p,h1,h2,h3,h4,h5,h6,blockquote,div",
            theme_advanced_buttons1:"styleselect,formatselect,fontselect,fontsizeselect,separator,forecolor,backcolor",
            theme_advanced_buttons2:"bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,bullist,numlist,separator,indent,outdent,separator,undo,redo,spellcheck",
            theme_advanced_buttons3:"cut,copy,paste,pastetext,pasteword,selectall,separator,link,unlink,anchor,image,separator,hr,removeformat,separator,charmap,separator",
            theme_advanced_buttons4:"tablecontrols,visualaid,separator,code,revize_help"
        };
        // ---------------------------------- //

        // Create a single form for editing every marker's InfoWindow
        editform = {
            "titleField": Element("input", null, { type:"text" }),
            "descField": Element("textarea", null, { "id":"descField" }),
            "saveBtn": Element("div", "Save", {"class":"button"}),
            "m": false, // the marker currently focused
            "setup": function(){
                this.m.editing = true;
                this.m.setDraggable(false);
                this.titleField.value = this.m.title;
                this.descField.value = this.m.desc;

                //iw.close(); // doesn't work, strangely
                iw.setContent(this.form);
                iw.open(map, this.m);
            },
            "saveIt": function(){
                //tinyMCE.get('descField').save();
                this.m.titleElem.innerHTML = this.m.title = this.titleField.value;
                this.m.descElem.innerHTML = this.m.desc = this.descField.value;
                this.m.setDraggable(true);
                this.m.editing = false;

                google.maps.event.trigger(this.m, "click");
            }
        };
        editform.form = Element("div", [
            Element("h1", "Edit Marker Info"), 
            Element("div", [editform.titleField, editform.descField, editform.saveBtn], { "class":"iwEditor" }),
            Element("br", null, { "clear":"all" })
        ], { "class":"maxIW" });

        google.maps.event.addListener(iw, "closeclick", function(){
            if ( editform.m.editing )
                editform.saveIt();
        });
        editform.saveBtn.onclick = function(){
            editform.saveIt();
        };
    }

    // populate map with markers from mapdata
    for ( var i in mapdata.markers ) {
        mapdata.markers[i] = newMark(mapdata.markers[i], i);
    }

    // -----auxilliary functions----- //
    // New Marker function
    // - creates a new marker and puts it on the map
    function newMark(data, i) {
        var m = new google.maps.Marker({
            position: data.loc,
            draggable: editable,
            "title": data.title
        });
        m.dataIndex = i;
        m.loc = data.loc;
        m.title = data.title;
        m.desc = data.desc;

        // callback stuff for editing
        m.editing = false;

        // InfoWindow content
        var iwContent = Element("div",
            [ m.titleElem = Element("h1", m.title), m.descElem = Element("div", m.desc) ],
            { "class": "iwContent" }
        );

        if (editable) {
            // Edit and Delete buttons
            var editBtn = Element("img", null, { "src":"images/edit/edit_small.jpg", "class":"button" });
            editBtn.style.cursor = "pointer";
            editBtn.onclick = function(){
                editform.setup();
            };

            var delBtn = Element("img", null, { "src":"images/edit/delete_small.jpg", "class":"button" });
            delBtn.style.cursor = "pointer";
            delBtn.onclick = function(){
                m.setMap(null);
                delete mapdata.markers[m.dataIndex]; // TODO: maybe use splice instead
                iw.close();
            };

            iwContent.appendChild( Element("div", [editBtn, delBtn]) );
        }

        // --- Marker Event Handlers --- //
        google.maps.event.addListener(m, "click", function(){
            if (editable && editform.m && editform.m.editing) editform.saveIt();

            iw.setContent(iwContent);
            iw.open(map, m);
            if (editable) editform.m = m;
        });
        google.maps.event.addListener(m, "dragstart", function(){
            if (editable && editform.m && editform.m.editing) editform.saveIt();
            iw.close();
        });
        google.maps.event.addListener(m, "dragend", function(e){
            m.loc = e.latLng;
        });

        m.setMap(map);
        return m;
    }

    // HTML element creation helper
    function Element(name, content, props) {
        var elem = d.createElement(name);
        if (content){
            if (typeof content == "string"){
                elem.innerHTML = content;
            } else if (content instanceof Array){
                for (var i in content){ elem.appendChild(content[i]); }
            } else {
                elem.appendChild(content);
            }
        }
        if (props){
            for (var i in props){
                if ("class" == i){
                    elem.className = props[i]; // because IE sucks
                }else{
                    elem.setAttribute(i, props[i]);
                }
            }
        }
        return elem;
    }

    // serialize function
    // - outputs a string representation of all the mapdata.
    function serialize() {
        return [
            "center:new google.maps.LatLng", mapdata.center.toString(),
            ",zoom:", String(mapdata.zoom), ",markers:[",
            (function(m, ret, i){
                for (i in m) {
                    if (!m[i]){continue;}
                    ret[ret.length] = [
                        "{loc:new google.maps.LatLng", m[i].loc.toString(),
                        ',title:', tinymce.util.JSON.serialize(m[i].title),
                        ',desc:', tinymce.util.JSON.serialize(m[i].desc), '}'
                    ].join('');
                }
                return ret;
             })(mapdata.markers, []).join(','),
            "]"
        ].join('');
    }

}
// EOF

