/**
 * Slide actions for events.
 *
 * AUTHOR Tim Baumgard
 *
 * Part of the Scout Portal Toolkit
 * Copyright 2009 Internet Scout Project
 * http://scout.wisc.edu
 */

// so we don't pollute the global namespace
(function($) {

    // global-ish vars
    var $clobber = $.clobber({"delay": 450});
    var eventCache = {};
    var $group = null;

    // constants
    var CONST = {
        "POINTERFILE": "SPTUI--ATECentral/images/pointer_left.gif",
        "URL": "index.php?P=EventApi"
    };

    $(document).ready(function(){
        // preload the pointer image
        $.preload(CONST.POINTERFILE);

        // show extra info for micro events
        $(".Event[class*=Micro]").mouseenter(function(){
            $this = $(this);

            // show extra info
            $clobber(function(){
                // get event
                var id = $this.attr("objectid");
                var event = getEvent(id);

                // show right away if it was in the cache, otherwise wait until
                // it's returned
                if (event) {
                    show(event, $this);
                } else {
                    // precondition: the event exists. otherwise this will loop
                    // continually. a global "isWorking" var could be used instead
                    $.wait(function(){  return eventCache[id];  }, function(){
                        show(getEvent(id), $this);
                    }, {"wakeInterval": 0});
                }
            });
        });

        // hide extra info for micro events
        $(".Event[class*=Micro]").mouseleave(function(){
            $clobber(function(){}, {"delay": 0});
            hide($(this));
        });

        // clobber displaying if a link is clicked for micro events
        $(".Event[class*=Micro] a").click(function(){
            $clobber(function(){}, {"delay": 0});
        });

        // release event button actions
        $(".Event .Release").confirm(function($clicked){
            var $event = $clicked.parents(".Event");
            var id = $event.attr("objectid");

            releaseEvent(id, function(json){
                if (json.status.code && json.status.code == "OK") {
                    $(".Release", $event).remove();
                    $(".Unreleased", $event).remove();
                } else {
                    alert(json.status.message);
                }
            });
        }, {"question":"Really?<br />", "or":"<br />or<br />"});

        // delete event button actions
        $(".Event .Delete").confirm(function($clicked){
            var $event = $clicked.parents(".Event");
            var id = $event.attr("objectid");

            deleteEvent(id, function(json){
                if (json.status.code && json.status.code == "OK") {
                    // get wrapper and event counter variables
                    var $wrapper = $event.parents(".List");
                    var $count = $wrapper.children(".Header").children(".EventsCount");

                    // remove event-less sections
                    if (parseInt($count.html()) <= 1) {
                        $parent = $wrapper.parents(".Events");
                        $wrapper.remove();

                        // if we deleted the last event
                        if ($parent.children().length <= 3) {
                            $noevents = $(document.createElement("DIV"))
                            $noevents.attr("class", "List").html("<p class=\"Header\">"+
                                "There are currently no events.</p>");
                            $("br", $parent).remove();
                            $parent.append($noevents);
                            $(".Events .OnBottom").remove();
                        }
                    }
                    // update count
                    else {
                        $count.html((parseInt($count.html())-1)+"");
                    }

                    // remove the elements
                    $event.remove();
                    $(".Separator[objectid="+id+"]").remove();
                }
            });
        }, {"question":"Really?<br />", "or":"<br />or<br />"});
    });

    // highlight the parent element
    function highlight($parent) {
        $parent.highlight({"color": "#CCC"})
        $(".Date, .Title a, .iCal a", $parent).css({"color":"#FFF"});
    };

    // unhighlight the parent element
    function unhighlight($parent) {
        $parent.unhighlight();
        $(".Date, .Title a, .iCal a", $parent).css({"color":"#929496"});
    };

    // show/position/etc
    function show(event, $parent) {
        // create/setup pointer image
        var $image = $("<img>").attr({  "src": CONST.POINTERFILE, "alt": ""  });

        // create date text
        var date = "";
        var days = Math.ceil((event.EndDate - event.StartDate)/86400)+1;
        if (days >= 2) {
            date = "<span class=\"StartDate\">"+
                $.date("F jS, Y", {"timestamp":event.StartDate*1000})+
                "</span> - <span class=\"EndDate\">"+
                $.date("F jS, Y", {"timestamp":event.EndDate*1000})+"</span> "+
                "("+days+" days)";
        } else {
            date = "<span class=\"StartDate\">"+
                $.date("F jS, Y", {"timestamp":event.StartDate*1000})+"</span>";
        }

        // create title text
        var title = (event.LongTitle != "") ? event.LongTitle : event.Title;

        // set up the widget
        var $widget = $("<div>").attr({"class":"EventInfo"})
        $widget.html("<span class=\"LongTitle\"><b>"+title +
                "</b></span><br /><span class\"Description\">"+
                event.Description+"</span>");

        // add location if set
        if (event.Location != "") {
            $widget.html($widget.html()+"<br /><b>Location:</b> " +
                "<span class=\"Location\">"+event.Location+"</span>");
        }

        // add date
        $widget.html($widget.html()+"<br /><b>Date:</b> "+date);

        // group the widget and the image
        $group = $([$widget.get(0), $image.get(0)]);

        // attach and position
        $(document.body).append($widget).append($image);
        $group.css({"opacity":0, "display":"block"}); // so that we can position
        $widget.positionRightOf($parent, {"extraLeft": 25});
        $image.positionLeftOf($widget, {"extraLeft": 7});

        // make visible and highlight parent
        $group.css({"opacity":1});
        highlight($parent);
    };

    // hide/remove/etc
    function hide($parent) {
        if ($group) {
            $group.css("display", "none").remove();
            unhighlight($parent);
        }
    };

    // no guarantee that this will return an event (say it doesn't exist)
    function getEvent(id) {
        if (!eventCache[id]) {
            fetchEvent(id);
        }

        return eventCache[id];
    };

    // fetch an event (if it exists) and cache it
    function fetchEvent(id) {
        // setup vars
        var id = escape(id);
        var params = {"ID":id, "Method":"GET", "ReturnType":"JSON"};

        // perform fetch
        $.getJSON(CONST.URL, params, function(json){
            // if everything is ok, cache the first object of the objects array
            if (json.status.code == "OK" && json.data.numObjects > 0) {
                eventCache[id] = json.data.objects[0];
            }
        });
    };

    // release an event
    function releaseEvent(id, callback) {
        // setup vars
        var id = escape(id);
        var params = {"ID":id, "Released":1, "Method":"PUT", "ReturnType":"JSON"};

        // perform put
        $.getJSON(CONST.URL, params, callback);
    };

    // delete an event
    function deleteEvent(id, callback) {
        // setup vars
        var id = escape(id);
        var params = {"ID":id, "Method":"DELETE", "ReturnType":"JSON"};

        // perform put
        $.getJSON(CONST.URL, params, callback);
    };

})(jQuery);
