jQuery(function($)
{
    /* SETTINGS
       -------- */
       
    // process settings assigned via typoscript (they are all strings, but we need different types)
    tx_projectnews_pi2_jsOptions.map.polyline.weight = parseInt(tx_projectnews_pi2_jsOptions.map.polyline.weight);
    tx_projectnews_pi2_jsOptions.map.polyline.zoomFactor = parseInt(tx_projectnews_pi2_jsOptions.map.polyline.zoomFactor);
    tx_projectnews_pi2_jsOptions.map.polyline.numLevels = parseInt(tx_projectnews_pi2_jsOptions.map.polyline.numLevels);
    tx_projectnews_pi2_jsOptions.map.initialView.lat = parseFloat(tx_projectnews_pi2_jsOptions.map.initialView.lat);
    tx_projectnews_pi2_jsOptions.map.initialView.lng = parseFloat(tx_projectnews_pi2_jsOptions.map.initialView.lng);
    tx_projectnews_pi2_jsOptions.map.initialView.zoom = parseInt(tx_projectnews_pi2_jsOptions.map.initialView.zoom);
    tx_projectnews_pi2_jsOptions.map.initialView.alignToMarkers = parseInt(tx_projectnews_pi2_jsOptions.map.initialView.alignToMarkers);
    tx_projectnews_pi2_jsOptions.map.infoWindow.maxWidth = parseInt(tx_projectnews_pi2_jsOptions.map.infoWindow.maxWidth);

    
    /* HELPER FUNCTIONS
       ---------------- */

    // also used for maximized marker title
    function renderProjectTitleHtml(project)
    {
        return '<a class="name" href="' + project.url + '">' + project.name + '</a>'
    }

    // full json info available
    function renderProjectHtml(project, isMaximized)
    {
        var html = '';
        var text;
        
        if (!isMaximized)
        {
            text = project.text;
            html += renderProjectTitleHtml(project);
        }
        else
        {
            text = project.text_complete;
        }
        
        html += '<div class="project-map-popup">'
              + '<div class="image-info">'
              + '<a class="image" href="' + project.url + '">' + project.image + '</a>'
              + '<br /><span class="stars"><img src="fileadmin/template/img/' + project.stars + 'stars.gif"></span>'
              + '</div>';
        
        if (!isMaximized)
        {
            html += '<div class="text" style="clear: both;">' + text + '</div>'
        }
        else
        {
            html += '<div class="text">' + text + '</div>'
        }
        
        html += '<a class="more" href="' + project.url + '">&raquo; weiterlesen</a>'
              + '</div';
             
        return html;
    }

    /* --------- */
    
    $('body').bind('unload', GUnload);

    var $loadingDiv = $('<div class="project-marker-loading"></div>')
        .css({
            display: 'block',
            background: 'url(' + tx_projectnews_pi2_jsOptions.resourceBaseUrl + 'ajax-spinner.gif) no-repeat 50% white',
            left: 0,
            top: 0,
            width: '100%',
            height: '100px',
            border: 0,
            padding: 0,
            margin: 0
        });
    
    var projectInfos = [];
    
    function initProjectInfo(partialProject)
    {
        projectInfos[partialProject.uid] =  {
            project:           partialProject,
            isFullyLoaded:     false,
            areNodesCreated:   false,
            doNodesNeedUpdate: null,
            contentNode:       null,
            maxTitleNode:      null,
            maxContentNode:    null
        }
    }
    
    function _updateProjectInfoNodes(projectUid)
    {
        var projectInfo = projectInfos[projectUid];
        
        var titleHtml = renderProjectTitleHtml(projectInfo.project);
        
        if (!projectInfo.areNodesCreated)
        {
                projectInfo.contentNode    = $('<div id="project-marker-content-'    + projectUid + '"></div>');
                projectInfo.maxTitleNode   = $('<div id="project-marker-maxtitle-'   + projectUid + '"></div>').html(titleHtml);
                projectInfo.maxContentNode = $('<div id="project-marker-maxcontent-' + projectUid + '"></div>');
                
                projectInfo.areNodesCreated = true;
                projectInfo.doNodesNeedUpdate = true;
        }
        
        if (projectInfo.doNodesNeedUpdate)
        {
            if (!projectInfo.isFullyLoaded)
            {
                projectInfo.contentNode.html(titleHtml).append($loadingDiv.clone());
                projectInfo.maxContentNode.append($loadingDiv.clone());
            }
            else
            {
                projectInfo.contentNode.html(renderProjectHtml(projectInfo.project, false));
                projectInfo.maxContentNode.html(renderProjectHtml(projectInfo.project, true));
            }
            projectInfo.doNodesNeedUpdate = false;
        }
    }
    
    function updateProjectInfo(project)
    {
        var projectInfo = projectInfos[project.uid];
        
        projectInfo.project = project;
        projectInfo.isFullyLoaded = true;
        projectInfo.doNodesNeedUpdate = true;
        
        if (projectInfo.areNodesCreated)
        {
            _updateProjectInfoNodes(project.uid);
        }
    }
    
    function getProjectInfo(projectUid, nodesRequired)
    {
        if (nodesRequired)
        {
            _updateProjectInfoNodes(projectUid);
        }
        return projectInfos[projectUid];
    }
    
    if (GBrowserIsCompatible())
    {
        var starIcons = [];

        var starIcon1 = new GIcon();
        starIcon1.image = tx_projectnews_pi2_jsOptions.resourceBaseUrl + 'star-overlay.png';
        starIcon1.iconSize = new GSize(25, 24);
        starIcon1.iconAnchor = new GPoint(12, 12);
        starIcon1.infoWindowAnchor = new GPoint(12, -2);
        starIcon1.shadow = tx_projectnews_pi2_jsOptions.resourceBaseUrl + 'star-overlay-shadow.png';
        starIcon1.shadowSize = new GSize(35, 24);
        starIcons[1] = starIcon1;
        
        // overlay with 2 or 3 stars currently look the same
        starIcons[2] = starIcon1;
        starIcons[3] = starIcon1;
 
        function createMarker(project)
        {
            var marker = new GMarker(project.point, {
                icon: starIcons[project.stars],
                title: project.name,
                clickable: true,
                draggable: false
            });
            marker.swfProjectUid = project.uid;
            
            return marker;
        }

        var map = new GMap2(document.getElementById('map_canvas'));

        var infoWindow = map.getInfoWindow();
        infoWindow.enableMaximize();

        // activate clickhandler (one handler works for all markers)
        GEvent.addListener(map, 'click', function(overlay, latLng, overlayLatLng)
        {
            if (overlay instanceof GMarker)
            {
                var marker  = overlay; // rename to make code more readable
                
                var projectInfo = getProjectInfo(marker.swfProjectUid, true);
                function displayInfoWindow()
                {
                    marker.openInfoWindow(projectInfo.contentNode.get(0), {
                        maxWidth:   tx_projectnews_pi2_jsOptions.map.infoWindow.maxWidth,
                        maxTitle:   projectInfo.maxTitleNode.get(0),
                        maxContent: projectInfo.maxContentNode.get(0)
                    });
                }
                displayInfoWindow();

                
                if (!projectInfo.isFullyLoaded)
                {
                    $.ajax(
                    {
                        type:     'GET',
                        url:      tx_projectnews_pi2_jsOptions.projectRequestUrl + '&imgsize=' + tx_projectnews_pi2_jsOptions.imgsize + '&uid=' + projectInfo.project.uid,
                        dataType: 'json',
                        success:  function(completeProject, status)
                        {
                            if (completeProject && completeProject.uid)
                            {
                                updateProjectInfo(completeProject);
                                displayInfoWindow();
                            }
                        }
                    });
                }
            }
        });
        
        map.addControl(new GMapTypeControl());
        map.addControl(new GLargeMapControl());
        // map.addControl(new GSmallMapControl()); // alternative to large map control
        
        /*
        // debugging: log center and zoom in javascript console. useful for determining fixed position and zoom level (see below)
        GEvent.addListener(map, 'moveend', function(){ console.log('moved to lat/lng', map.getCenter().y, map.getCenter().x) });
        GEvent.addListener(map, 'zoomend', function(oldlevel, newlevel){ console.log('zoomed to', newlevel); });
        //*/

        // set fixed position and zoom level (see debugging code above)
        map.setCenter(new GLatLng(tx_projectnews_pi2_jsOptions.map.initialView.lat, tx_projectnews_pi2_jsOptions.map.initialView.lng), tx_projectnews_pi2_jsOptions.map.initialView.zoom);
        
        // add polyline with outline of Südwestfalen. set by polyline-utility
        // http://code.google.com/intl/de/apis/maps/documentation/polylineutility.html
        // (don't forget to close the polyline in the utility by _manually_entering_
        // the coordinates of the first point as coordinates for the last one.)
        var encodedPolyline = new GPolyline.fromEncoded(tx_projectnews_pi2_jsOptions.map.polyline);
        map.addOverlay(encodedPolyline);
        
        GDownloadUrl(tx_projectnews_pi2_jsOptions.markersRequestUrl, function(data)
        {
            var xml = GXml.parse(data);
            var markers = xml.documentElement.getElementsByTagName('marker');
            
            if (tx_projectnews_pi2_jsOptions.map.initialView.alignToMarkers)
            {
                var bounds = new GLatLngBounds();
            }
            
            for (var i = 0; i < markers.length; i++)
            {
                var project = {
                    name:  markers[i].getAttribute('name'),
                    uid:   parseInt(markers[i].getAttribute('uid')),
                    stars: parseInt(markers[i].getAttribute('stars')),
                    lat:   parseFloat(markers[i].getAttribute('lat')),
                    lng:   parseFloat(markers[i].getAttribute('lng')),
                    url:   markers[i].getAttribute('url')
                }
                
                project.point = new GLatLng(project.lat, project.lng)
                project.marker = createMarker(project);

                initProjectInfo(project);
                
                map.addOverlay(project.marker);
                
                if (tx_projectnews_pi2_jsOptions.map.initialView.alignToMarkers)
                {
                    bounds.extend(project.point);
                }
            }
            
            // set map viewport and zoom to bounding box of all markers
            if (tx_projectnews_pi2_jsOptions.map.initialView.alignToMarkers)
            {
                map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
            }

        });
        
    }
});

