// Main JS library for Sk


// XXX All global things must be prefixed with `Sk', or `sk_' for functions.
//     All objects in JSON.

// TODO   On each page reload, set css class for active elements:
//        1. main menu item
//        2. tab of main screen
//        3. tab of tricorder
//        Server script may change view for more than one element and we
//        must reflect this change in GUI.

var sk_is_map_view = false;

/**
 * Decorator for Ajax.Request
 *
 * Do not call Ajax.Request directly. Use this function instead, because
 * it handles disabling/enabling GUI elements and showing the sandclock.
 */
function sk_ajax_request(url, options)
{
	// TODO  Disable GUI elements
	// TODO  Show sandclock
	new Ajax.Request(url, options);
	// TODO Hide sandclock
	// TODO Enable GUI elements
}

/**
 * Object to perform actions
 */
var SkAction =
{
	perform : function(url, param)
	{
        sk_ajax_request(
            url,
            {
                method    : 'get',
				parameters: param,
                onSuccess : function(transport)
                {
                    var s = transport.responseText || '<p>Empty. This should not happen&trade;</p>';
                    $('mainScreen').update(s);
                },
                onFailure : function()
                {
					// noop
                    alert('AAAGH, sth went wrong while talking to the server. Please try again.');
                }
            }
        );
	},

	performAndTricorder: function(url, param)
	{
        sk_ajax_request(
            url,
            {
                method    : 'get',
				parameters: param,
                onSuccess : function(transport)
                {
                    var s = transport.responseText || '<p>Empty. This should not happen&trade;</p>';
                    $('mainScreen').update(s);
                    SkTricorder.fullreload();
                },
                onFailure : function()
                {
					// noop
                    alert('AAAGH, sth went wrong while talking to the server. Please try again.');
                }
            }
        );
	}
};

/**
 * Object for MainScreen
 */
var SkMainScreen =
{
    /**
     * Changes between tabs
     */
    changeTab : function(tab_name, id)
    {

        // ---[ 1. Switch Tab ]---------------------------------------------

        /*
        var t_to = $('mainScreenTab' + tab_name.charAt(0).toUpperCase() + tab_name.substr(1));
		// Maybe we have to switch to a view which has no tab
		if (t_to) {
			// Remove active CSS from current tab
			var t_from = document.getElementsByClassName('li_ms_selected');
			// Maybe we have to switch from a view which has no tab
			if (t_from) {
				t_from[0].removeClassName('li_ms_selected');
			}
			// Set active CSS to new tab
			t_to.addClassName('li_ms_selected');
		}
		// If new tab is ADD_FORM, also switch Tricorder to categories view
		if (tab_name == 'addForm') {
			SkTricorder.changeTab('categories');
		}
        */
        // ---[ 2. Let AJAX fetch the needed view ]-------------------------
        // ---[    and put the view into its place ]------------------------

        var url = pym_url('Front/MainScreen/' + tab_name + 'View');
		if (id != undefined) url += '/' + id;
        sk_ajax_request(
            url,
            {
                method    : 'get',
                onSuccess : function(transport)
                {
                    var s = transport.responseText || '<p>Empty. This should not happen&trade;</p>';
                    $('mainScreen').update(s);
                    SkTricorder.fullreload();
                    window.location.href = "#";
                },
                onFailure : function()
                {
                    var s = '<p>AAAGH, sth went wrong while talking to the server. Please try again.</p>';
                    $('mainScreenView').update(s);
                    window.location.href = "#";
                }
            }
        );

    },

    /**
     * Sets a special search-view
     */
    setSearch : function(view_name)
    {
        // ---[ 1. Let AJAX tell about new node_id     ]-------------------
        // ---[    and re-render the view in its place ]-------------------

        var url = pym_url('Front/MainScreen/setSearch');
        sk_ajax_request(
            url,
            {
                method     : 'get',
                parameters : { search : view_name },
                onSuccess  : function(transport)
                {
                    var s = transport.responseText || '<p>Empty. This should not happen&trade;</p>';
                    $('mainScreen').update(s);
                },
                onFailure  : function()
                {
                    var s = '<p>AAAGH, sth went wrong while talking to the server. Please try again.</p>';
                    $('mainScreenView').update(s);
                }
            }
        );
    },

    /**
     * Sets the current page in list view
     */
    setPageNum : function(pn)
    {
        // ---[ 2. Let AJAX fetch the needed view ]-------------------------
        // ---[    and put the view into its place ]------------------------

        var url = pym_url('Front/MainScreen/setPageNum/' + pn);
        sk_ajax_request(
            url,
            {
                method    : 'get',
                onSuccess : function(transport)
                {
                    var s = transport.responseText || '<p>Empty. This should not happen&trade;</p>';
                    $('mainScreen').update(s);
                    window.location.href = "#";
                },
                onFailure : function()
                {
                    var s = '<p>AAAGH, sth went wrong while talking to the server. Please try again.</p>';
                    $('mainScreenView').update(s);
                    window.location.href = "#";
                }
            }
        );

    },

    /**
     * Sets the sort order in list view
     */
    setSortField : function(sf)
    {
        var url = pym_url('Front/MainScreen/setListViewSorterAjax?sb_listViewSorter=' + encodeURI(sf));
        sk_ajax_request(
            url,
            {
                method    : 'get',
                onSuccess : function(transport)
                {
                    var s = transport.responseText || '<p>Empty. This should not happen&trade;</p>';
                    $('mainScreen').update(s);
                },
                onFailure : function()
                {
                    var s = '<p>AAAGH, sth went wrong while talking to the server. Please try again.</p>';
                    $('mainScreenView').update(s);
                }
            }
        );
    },

    /**
     * Reloads widget without changing anything
     */
    reload : function()
    {
		// If we are in MapView, only update the markers
		//if (sk_ggl_map) {
		if (sk_is_map_view == true) {
			SkGglMap.updateMarkers();
			return;
		}

        var url = pym_url('Front/MainScreen/reload');
        sk_ajax_request(
            url,
            {
                method    : 'get',
                onSuccess : function(transport)
                {
                    var s = transport.responseText || '<p>Empty. This should not happen&trade;</p>';
                    $('mainScreen').update(s);
                },
                onFailure : function()
                {
                    var s = '<p>AAAGH, sth went wrong while talking to the server. Please try again.</p>';
                    $('mainScreenView').update(s);
                }
            }
        );
    },

    /* changeProfileViews */
    activeProfileView : 'mainScreenDetailsMain',

    changeProfileView : function(to_id)
    {

        var first_load = false;
        if (to_id == 'first_load') {
            to_id = 'mainScreenDetailsMain'; //this.activeProfileView;
            first_load = true;
        }
        if (this.activeProfileView !== null && !first_load) {
            $(this.activeProfileView).hide();
            $("a_"+this.activeProfileView).removeClassName("a_selected");
        }
        $(to_id).show();
        $("a_"+to_id).addClassName("a_selected");
        this.activeProfileView = to_id;
    },

    /* changeProfileViews */
    //activeProfileEdit : null,
    activeProfileEdited : false,

    changeProfileEdit : function(to_id)
    {
        var first_load = false;
        if (to_id == 'first_load') {
            to_id = this.activeProfileView;
            first_load = true;
        }
        if (this.activeProfileEdited) {
            if (confirm("Änderungen, die Sie in diesem Bereich vorgenommen haben, gehen verloren.\n\nKlicken Sie auf Abbrechen, um die Daten vorher zu speichern.")) {
                 //TODO Abfrage, ob sich was geändert hat...
                if (this.activeProfileView !== null && !first_load) {
                    $(this.activeProfileView).hide();
                    $("a_"+this.activeProfileView).removeClassName("a_selected");
                }
                $(to_id).show();
                $("a_"+to_id).addClassName("a_selected");
                $('activeView').value = to_id;
                this.activeProfileView = to_id;
                this.activeProfileEdited = false;
            }
        }
        else {
            //TODO Abfrage, ob sich was geändert hat...
            if (this.activeProfileView !== null && !first_load) {
                $(this.activeProfileView).hide();
                $("a_"+this.activeProfileView).removeClassName("a_selected");
            }
            $(to_id).show();
            $("a_"+to_id).addClassName("a_selected");
            $('activeView').value = to_id;
            this.activeProfileView = to_id;
        }
    },

    ProfileEdited : function() {
        this.activeProfileEdited = true;
    }
};


/**
 * Object for Tricorder
 */
var SkTricorder =
{
    /**
     * Reloads tricorder
     */
    reload : function()
    {
        var url = pym_url('Front/Tricorder/reload');
        sk_ajax_request(
            url,
            {
                method    : 'get',
                onSuccess : function(transport)
                {
                    var s = transport.responseText || '<p>Empty. This should not happen&trade;</p>';
                    $('tricorderView').update(s);
                    //For Categoriy Animation
                    SkTricorder.displayCategoryChildren(false);
                },
                onFailure : function()
                {
                    var s = '<p>AAAGH, sth went wrong while talking to the server. Please try again.</p>';
                    $('tricorderView').update(s);
                }
            }
        );
        //For all children of myMenu to be closed
        this.activeChildren = null;
    },

    /**
     * Reloads tricorder, tabs and search
     */
    fullreload : function()
    {
        var url = pym_url('Front/Tricorder/fullreload');
        sk_ajax_request(
            url,
            {
                method    : 'get',
                onSuccess : function(transport)
                {
                    var s = transport.responseText || '<p>Empty. This should not happen&trade;</p>';
                    $('tricorder').update(s);
                    //For Categoriy Animation
                    SkTricorder.displayCategoryChildren(false);
                },
                onFailure : function()
                {
                    var s = '<p>AAAGH, sth went wrong while talking to the server. Please try again.</p>';
                    $('tricorder').update(s);
                }
            }
        );
        //For all children of myMenu to be closed
        this.activeChildren = null;
    },

    /**
     * Changes between tabs
     */
    changeTab : function(tab_name)
    {
        // ---[ 1. Switch Tab ]---------------------------------------------

        // Remove active CSS from current tab
        var t = document.getElementsByClassName('li_tri_selected');
        t[0].removeClassName('li_tri_selected');
        // Set active CSS to new tab
        t = $('tricorderTab' + tab_name.charAt(0).toUpperCase() + tab_name.substr(1));
        t.addClassName('li_tri_selected');



        // ---[ 2. Let AJAX fetch the needed view ]-------------------------
        // ---[    and put the view into its place ]------------------------

        var url = pym_url('Front/Tricorder/' + tab_name + 'View');
        sk_ajax_request(
            url,
            {
                method    : 'get',
                onSuccess : function(transport)
                {
                    var s = transport.responseText || '<p>Empty. This should not happen&trade;</p>';
                    $('tricorderView').update(s);
                    //For Categoriy Animation
                    SkTricorder.displayCategoryChildren(false);
                },
                onFailure : function()
                {
                    var s = '<p>AAAGH, sth went wrong while talking to the server. Please try again.</p>';
                    $('tricorderView').update(s);
                }
            }
        );
        //For all children of myMenu to be closed
        this.activeChildren = null;
    },

    /**
     * Selects a node in categoriesView
     */
    selectNode : function(node_id)
    {
        // ---[ 1. Let AJAX tell about new node_id     ]-------------------
        // ---[    and re-render the view in its place ]-------------------

        var url = pym_url('Front/Tricorder/selectNode');
        sk_ajax_request(
            url,
            {
                method     : 'get',
                parameters : { id : node_id },
                onSuccess  : function(transport)
                {
                    var s = transport.responseText || '<p>Empty. This should not happen&trade;</p>';
                    $('tricorderView').update(s);
					// ---[ 2. Trigger refresh of MainScreen ]-------------------------
					// Do not do this after sk_ajax_request(). The Ajax request processes
					// *asynchronously*! It may happen that main screen reloads before
					// the other request set the new viewstate!
					SkTricorder.displayCategoryChildren(true);
					// TODO In VIEW_MAP only load new markers, in all other
					// TODO views, reload the whole MainScreen
					SkMainScreen.reload();

                },
                onFailure  : function()
                {
                    var s = '<p>AAAGH, sth went wrong while talking to the server. Please try again.</p>';
                    $('tricorderView').update(s);
                }
            }
        );
    },


    /*

    */
    displayCategoryChildren : function (animate) {
        try {
            if (animate)
                Effect.SlideDown('div_tricorderCategoriesViewChildren',{duration:0.2});
            else
                $('div_tricorderCategoriesViewChildren').show();


            //setTimeout("Effect.SlideDown('div_tricorderCategoriesViewChildren',{duration:0.2});",500);
        }
        catch (e) {}

    },


    /*
    Display Children form MyMenu
    */
    activeChildren : null,

    displayChildren : function(children_id)
    {
        //alert($("MyChildren"+children_id).style.display);
        if (this.activeChildren == children_id) {
            Effect.SlideUp("MyChildren"+children_id,{duration:0.2});
            this.activeChildren = null;

        }
        else {
            if (this.activeChildren != null) {
                Effect.SlideUp("MyChildren"+this.activeChildren,{duration:0.2});
            }
            this.activeChildren = children_id;
            Effect.SlideDown("MyChildren"+children_id,{duration:0.2});
        }


    },

    /*
    Helptext
    */

    timer : null,

    setHilfe : function(help_id)
    {
        clearTimeout(this.timer);
        $("tricorderHelpText").innerHTML = $(help_id+"_help_text").innerHTML;
        $("tricorderFree").hide();
        Effect.Appear("tricorderHelpText",{duration: 0.2});
    },

    clearHilfe : function() {
        $("tricorderHelpText").hide();
        this.timer = setTimeout('Effect.Appear("tricorderFree",{duration: 0.2});',500);
    }

};

function sk_add_load_event(func)
{
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	} else {
		window.onload = function()
		{
			oldonload();
			func();
		}
	}
}

function sk_add_unload_event(func)
{
	var oldonunload = window.onunload;
	if (typeof window.onunload != 'function') {
		window.onunload = func;
	} else {
		window.onunload = function()
		{
			oldonunload();
			func();
		}
	}
}

function sk_get_skin_url(path) {
    var l = window.location.href;
    var URL = l.split('main.php')[0];
    return URL + path;
}

// ===[ For GglMap ]=======

// Map View defines a global var 'sk_ggl_map' in which the instance of the map
// will be stored.

var SkGglMap =
{
	home_lat : null,
	home_long : null,
	home_info: null,

	icon_home : null,
	icon_request : null,
	icon_group : null,
	icon_activity : null,
	icon_user : null,

	listener_update_markers : null,

	initMap : function(not_compatible_msg, center_lat, center_long, start_zoom,
			home_lat, home_long, home_info)
	{
		var map_elem = $('ggl_map');
		home_info.replace(/§/, "'");

		// 1. Check compatibility with browser
		if (! GBrowserIsCompatible()) {
			map_elem.update(not_compatible_msg);
			return false;
		}
		// 2. Do nothing here if map already is initialised
		if (undefined != this.sk_ggl_map) {
			return true;
		}
		// 3. Initialise
		this.home_lat  = home_lat;
		this.home_long = home_long;
		this.home_info = home_info;

		sk_ggl_map = new GMap2(map_elem);
		var loc = new GLatLng(center_lat, center_long);
		sk_ggl_map.setCenter(loc, start_zoom);
		sk_ggl_map.addControl(new GSmallMapControl());
		sk_ggl_map.addControl(new GScaleControl());
		sk_ggl_map.addControl(new GMapTypeControl());
		this.updateMarkers();
		// zoomend also triggers moveend, so we don't need a listener here
//		GEvent.addListener(sk_ggl_map,'zoomend',function() {
//			SkGglMap.updateMarkers();
//		});
		SkGglMap.listener_update_markers = GEvent.addListener(sk_ggl_map,
			'moveend', function() {
                //console.debug('moveend');
                if (! SkGglMap.has_win) SkGglMap.updateMarkers();
			}
		);
		// We listen to opening and closing of info windows:
		// On opening, we deregister update_markers, because the window might
		// scroll the map and update_markers would close the window.
		// On closing then window, we register update_markers again and call it
		// to take measures for the new viewport.
		GEvent.addListener(sk_ggl_map, 'infowindowopen', function() {
            SkGglMap.has_win = true;
            //console.debug('info_open');
			//GEvent.removeListener(SkGglMap.listener_update_markers);
		});
		GEvent.addListener(sk_ggl_map, 'infowindowclose', function() {
            //console.debug('info_close');
            /*
			SkGglMap.listener_update_markers = GEvent.addListener(sk_ggl_map,
				'moveend', function() {
                    //console.debug('moveend_2');
					SkGglMap.updateMarkers();
				}
			);
            */
			SkGglMap.updateMarkers();
		});

		this.icon_home = new GIcon();
		this.icon_home.image = sk_get_skin_url('/Skin/Default/icons/map/icon_home.png');
		this.icon_home.iconSize = new GSize(20, 18);
		this.icon_home.iconAnchor = new GPoint(6, 20);
		this.icon_home.infoWindowAnchor = new GPoint(5, 1);

		this.icon_request = new GIcon();
		this.icon_request.image = sk_get_skin_url('/Skin/Default/icons/map/icon_request.png');
		this.icon_request.iconSize = new GSize(35, 21);
		this.icon_request.iconAnchor = new GPoint(6, 20);
		this.icon_request.infoWindowAnchor = new GPoint(5, 1);

		this.icon_group = new GIcon();
		this.icon_group.image = sk_get_skin_url('/Skin/Default/icons/map/icon_group.png');
		this.icon_group.iconSize = new GSize(50, 40);
		this.icon_group.iconAnchor = new GPoint(6, 20);
		this.icon_group.infoWindowAnchor = new GPoint(5, 1);

		this.icon_activity = new GIcon();
		this.icon_activity.image = sk_get_skin_url('/Skin/Default/icons/map/icon_activity.png');
		this.icon_activity.iconSize = new GSize(35, 23);
		this.icon_activity.iconAnchor = new GPoint(6, 20);
		this.icon_activity.infoWindowAnchor = new GPoint(5, 1);

		this.icon_user = new GIcon();
		this.icon_user.image = sk_get_skin_url('/Skin/Default/icons/map/icon_user.png');
		this.icon_user.iconSize = new GSize(42, 36);
		this.icon_user.iconAnchor = new GPoint(6, 20);
		this.icon_user.infoWindowAnchor = new GPoint(5, 1);

		return true;
	},

	createMarker : function(latlong, content, icon)
	{
		var m = new GMarker(latlong,icon);
		GEvent.addListener(m, 'click',
			function()
			{
				var m_content = content;
				m.openInfoWindowHtml(m_content);
			}
		);
		return m;
	},

	getMapState : function()
	{
		var center = sk_ggl_map.getCenter();
		var size   = sk_ggl_map.getSize();
		var zoom   = sk_ggl_map.getZoom();
		var bounds = sk_ggl_map.getBounds();
		var sw     = bounds.getSouthWest();
		var ne     = bounds.getNorthEast();
		var ms = {
			center_lat : center.lat(),
			center_long: center.lng(),
			ne_lat     : ne.lat(),
			ne_long    : ne.lng(),
			sw_lat     : sw.lat(),
			sw_long    : sw.lng(),
			size_w     : size.width,
			size_h     : size.height,
			zoom       : zoom
		}
		return ms;
	},

	updateMarkers : function()
	{
        SkGglMap.has_win = false;
		// Fetch marker data
        var url = pym_url('Front/Map/getMarkerData');
		// Get viewport and zoom level of map and provide them
		// as parameters of request, so server can better filter the
		// resultset.
		ms = SkGglMap.getMapState();
        sk_ajax_request(
            url,
            {
                method    : 'get',
				parameters: ms,
                onSuccess : function(transport)
                {
                    var data = transport.responseText.evalJSON();
					SkGglMap.displayMarkers(data);
                },
                onFailure : function()
                {
                    var s = '<p>AAAGH, sth went wrong while talking to the server. Please try again.</p>';
                    $('mainScreenMapView').update(s);
                }
            }
        );
	},

	displayMarkers : function(data)
	{
		var loc, m;
		var dbg, q, it;
		// Lets check if we shall print the data for debugging
		dbg = $("ggl_map_debug");
		if (dbg) {
			q = data.shift();
		}

		sk_ggl_map.clearOverlays();
		// Set user home marker
		loc = new GLatLng(SkGglMap.home_lat, SkGglMap.home_long);
		m = SkGglMap.createMarker(loc, SkGglMap.home_info, SkGglMap.icon_home);
		sk_ggl_map.addOverlay(m);
		// Set markers for data
		it = data.shift();
		var icon;
		switch (it) {
			case 'requests':
				icon = SkGglMap.icon_request;
				break;
			case 'groups':
				icon = SkGglMap.icon_group;
				break;
			case 'activities':
				icon = SkGglMap.icon_activity;
				break;
			case 'users':
				icon = SkGglMap.icon_user;
				break;
			default:
				icon = SkGglMap.icon_home;
		}
		for (var i=0, len=data.length; i<len; ++i) {
			row = data[i];
			// TODO  Determine which icons are on the same pixel and use
			//       some random displacement
			loc = new GLatLng(row.coord_lat, row.coord_long);
			var m = SkGglMap.createMarker(loc, row.content, icon);
			sk_ggl_map.addOverlay(m);
		}
		// For debugging map data
		if (dbg) {
			var s = '<table border="1" cellspacing="0">';
			for (var i=0, len=data.length; i<len; ++i) {
				row = data[i];
				s += '<tr>'
					+ '<td>' + i + '</td>'
					+ '<td>' + row.id + '</td>'
					+ '<td>' + row.distance + '</td>'
					+ '<td>' + row.coord_lat + '</td>'
					+ '<td>' + row.coord_long + '</td>'
					+ '<td>' + row.content.replace(/</, '&lt;').replace(/>/, '&gt;') + '</td>'
					+ '</tr>';
			}
			s += '</table>';
			s += '<p><tt>' + q + '</tt></p>';
			dbg.update(s);
		}
	}
};
