/**
 * dovoEvents
 */
var dovoEvents = {

    events: [],
    size: undefined,            // total events found

    scroll_mutex: true,         // poor man's semaphore

    renderEvents: function(data, sizeNode, listNode) {
        dovoEvents.size = data.size;
        $(sizeNode).text( data.sizeText );

        // reset if first page
        if ( data.page == 1 ) {
            $( listNode ).html('');
            dovoEvents.clearEvents();
        }

        // no events found :(
        if ( dovoEvents.size == 0 ) {
            $( listNode ).html( '<div id="noevents"> \
<img src="/images/star_404.png" alt="Sad star" /> \
<h1>No event found</h1> \
Try broadening your search criteria \
</div>' );
            return;
        }

        $(data.events).each( function() {
            // Prepare data
            this.date_start = new Date( this.date_start );
            this.id = "event-" + this.id;

            if ( dovoEvents.events.length == 0 ||
                 (this.date_start - dovoEvents.events[dovoEvents.events.length-1].date_start) != 0 ) {
                     var h2 = $('<h2>', {'class': 'events'}).text(this.date_start_i18n);
                     var ul = $('<ul>', {'class': 'events'});
                     var node = $('#moar', listNode);
                     if ( node.html() ) {
                         node.before( h2 ).before( ul );
                     }
                     else {
                         $(listNode).append( h2 ).append( ul );
                     }
            }

            var li_template =
'<li id="{{id}}"> \
  {{#image}} \
  <div class="image"> \
    <img src="{{image}}" alt="{{name}} poster"> \
  </div> \
  {{/image}} \
  <div class="summary"> \
    <h3>{{name}}</h3> \
    <p><span class="venue">@ {{venue.name}}</span>, {{venue.city}}</p> \
    <p class="artists">{{artists}}</p> \
  </div> \
  <dl class="details" style="display:none;"> \
  </dl> \
</li>';
            var marker = dovoGMap.addEventToMap({
                lat:  this.venue.lat,
                lng:  this.venue.lng,
                name: this.name + ' @ ' + this.venue.name,
                id:   this.id
            });
            this.marker = marker;
            var li = $( $.mustache( li_template, this ) )
                    .click(function() {
                        dovoEvents.renderDetails( this );
                        marker.toggleInfo();
                    });
            $('ul:last', listNode).append( $(li) );

            dovoEvents.events.push( this );
        });

        dovoEvents.renderMoarButton( data, listNode );
    },

    renderMoarButton: function(data, listNode) {
        if ( $('#moar', listNode).length == 0 && dovoEvents.events.length != 0 ) {
            $( listNode ).append( $('<a>', {'id': 'moar'}).text('_').button() );
        }
        if ( data.page < data.totalPages ) {
            $( '#moar', listNode )
                .button( "option", "label", "Show more..." )
                .button('enable')
                .click( dovoEvents.form.nextPage );
        }
        else {
            $( '#moar', listNode )
                .button( "option", "label", "No more events to show" )
                .button('disable')
                .unbind();
        }
    },

    renderTags: function(data, tagNode) {
        // reset if first page
        if ( data.page == 1 ) {
            $( tagNode ).html('');
        }
        $( data.tags ).each( function() {
            $(tagNode).append( $('<div>', {'class': 'tag'}).append( $('<a>').text( this.name ) ) );
        });
    },

    renderDetails: function(node) {
        var event_id = $(node).attr( 'id' ).replace(/event-/, "");
        var dl =
'<table> \
\
  <tr> \
    <th>Who</th> \
    <td> \
      {{#artists}} \
      <p class="artists">{{.}}</p> \
      {{/artists}} \
    </td> \
  </tr> \
\
  <tr> \
    <th>When</th> \
    <td>{{event.datetime_start}}</td> \
  </tr> \
\
  <tr> \
    <th>Where</th> \
    <td> \
      <p class="venue">{{venue.name}}<\p> \
      <p>{{venue.address}}</p> \
    </td> \
  </tr> \
\
  {{#event.price}} \
  <tr> \
    <th>Price</th> \
    <td>{{event.price}}</td> \
  </tr> \
  {{/event.price}} \
\
  {{#event.description}} \
  <tr> \
    <th>What</th> \
    <td>{{event.description}}</td> \
  </tr> \
  {{/event.description}} \
\
  <tr> \
    <th>Last update</th> \
    <td>{{event.updated_at}}</td> \
  </tr> \
\
  <tr> \
    <th>Sources</th> \
    <td> \
      {{#sources}} \
      <a href="{{event_url}}" target="_blank"><img src="{{icon}}" height="16" width="16" alt="{{name}} icon" />&nbsp;{{name}}</a><br> \
      {{/sources}} \
    </td> \
  </tr> \
\
  <tr> \
    <th>Tags</th> \
    <td> \
      {{#tags}} \
      <div class="tag"><a>{{name}}</a></div> \
      {{/tags}} \
    </td> \
  </tr> \
\
</table>';

        if ( $(node).hasClass( 'expanded' ) ) {
            $('dl', node).slideFadeToggle( 'fast' );
            $(node).removeClass( 'expanded' );
        }
        else {
            $.ajax({
                url: "/events/" + event_id,
                dataType: 'json',
                beforeSend: dovoUI.spinner.start, 
                complete: dovoUI.spinner.stop,
                context: node,
                success: function( data ) {
                    $(node).addClass( 'expanded' );

                    $('dl', node).html( $.mustache(dl, data) ).slideFadeToggle( 'fast' );
                    $('a', node).click(function(e) {
                        e.stopPropagation();
                    });
                }
            });
        }
    },

    // Functions to call when events rendering ends
    renderCallbacks: function() {
        dovoGMap.setZoom();
        dovoEvents.scroll_mutex = true;
    },

    scrollForMoar: function() {
        var moar_zone = 50;         // bottom trigger zone height in px

        $(window).scroll( function(event) {
            var hidden = $(document).height() - $(window).height() - moar_zone;
            if ( dovoEvents.scroll_mutex &&
                 $(window).scrollTop() >= hidden &&
                 dovoEvents.events.length < dovoEvents.size ) {
                     dovoEvents.scroll_mutex = false;
                     dovoEvents.form.nextPage();
            }
        });
    },

    clearEvents: function() {
        $(dovoEvents.events).each( function() {
            this.marker.remove();
        } );
        dovoEvents.events = [];
    },

    initialize: function() {
        dovoEvents.scrollForMoar();
        dovoEvents.form.initialize();
    },

};

/**
 * dovoEvents.form
 */
dovoEvents.form = {

    whereShow: function(){
        var obj = $('.where-box');
        $('.param, .label', '.where-box').unbind();
        obj.find('.control')
            .slideFadeToggle('fast', function(){ $('#where').focus(); });
        obj.find('.label > a.toggle')
            .text("Close")
            .click( dovoEvents.form.whereHide );
        return false;
    },

    whereHide: function() {
        var obj = $('.where-box');
        $(this).unbind();
        obj.find('.label > a.toggle').text("Choose city");
        obj.find('.control')
            .slideFadeToggle('fast', function() {
                         $('.param, .label', '.where-box').click( dovoEvents.form.whereShow ); });
        return false;
    },

    whereSetPosition: function(lat, lng, address, address_label) {
        address_label = address_label || address;
        $('#where').val( address );
        $('.param', '.where-box').text( address_label );
        $('#lat').val( lat );
        $('#lng').val( lng );
        $('#page').val(1);
        $('#search').submit();
    },

    whenShow: function(){
        var obj = $('.when-box');
        $('.param, .label', '.when-box').unbind();
        obj.find('.control')
            .slideFadeToggle('fast');
        obj.find('.label > a.toggle')
            .text("Close")
            .click( dovoEvents.form.whenHide );
        return false;
    },

    whenHide: function() {
        var obj = $('.when-box');
        $(this).unbind();
        obj.find('.label > a.toggle').text("Choose date");
        obj.find('.control')
            .slideFadeToggle('fast', function() {
                         $('.param, .label', '.when-box').click( dovoEvents.form.whenShow ); });
        return false;
    },

    whenChange: function(date_from) {
        var label_from = 'From ';
        label_from += (date_from == 'Thu 23 Feb, 2012')? 'Today' : date_from;
        $('.param', '.when-box').text( label_from );
        $('#page').val(1);
        $('#search').submit();
    },

    nextPage: function() {
        var value = $('#page').val();
        $('#page').val( parseInt(value) + 1 );
        $('#search').submit();
    },

    beforeSend: function() {
        dovoUI.spinner.start();
        if ( $('#page').val() == 1 ) {
            $('#content-left > *').fadeTo( 500, 0.5 );
            $('.tagcloud > *').fadeTo( 500, 0.5 );
        }
    },

    initialize: function() {
        // Extend jQuery autocomplete
        $.widget( "custom.eventAutocomplete", $.ui.autocomplete, {
            _renderMenu: function( ul, items ) {
                var self = this,
                    currentType = "";
                $.each( items, function( index, item ) {
                    if ( item.type != currentType ) {
                        ul.append( "<li class='ui-menu-item ui-autocomplete-type'>" + item.type + "</li>" );
                        currentType = item.type;
                    }
                    self._renderItem( ul, item );
                });
            }
        });

        // Attach events to form elements

        // q box
        $('#q').placeholder();
        $('#q').observe_field( 0.5, function() {
            $('#page').val(1);
            $('#search').submit();
        });
        $("#q").eventAutocomplete({
            source: function(request, response) {
                $.ajax({
                    url: "/events/autocomplete",
                    dataType: 'json',
                    data: {
                        q: request.term,
                    },
                    success: function( data ) {
                        response( data );
                    }
                });
            },
            minLength: 2,
            delay: 100,
            appendTo: '#event-autocomplete',
        });

        // where box
        $('.param, .label', '.where-box').click( dovoEvents.form.whereShow );
        $('#where').change( function() {
            if( $(this).val() != ':everywhere' ) {
                dovoGMap.geocodeMyAddress({
                    address: $(this).val(),
                    radius: parseInt($('#radius').val()) * 1000,
                    callback: dovoEvents.form.whereSetPosition
                });
                $('#radius-slider').slider("enable");
            }
            else {
                dovoEvents.form.whereSetPosition( '', '', ':everywhere', "Everywhere" );
                dovoGMap.resetMyMarker();
                $('#radius-slider').slider("disable");
            }
        });
        $('#geolocate').click( function() {
            dovoGMap.geolocateMyPosition({
                radius: parseInt($('#radius').val()) * 1000,
                callback: dovoEvents.form.whereSetPosition,
                callbackError: function(message) {
                    $('#error .message').text( message );
                    $('#error').dialog({
                        modal: true,
                        resizable: false,
                        title: 'Error',
                        buttons: {
                            OK: function() {
                                $( this ).dialog( "close" );
                            }
                        },
                        close: function(event, ui) {
                            if ( $('#where').val() == '' ) {
                                $('#everywhere').click();
                            }
                        }
                    }); }
            });
            $('#radius-slider').slider("enable");
            return false;
        }).button();
        $('#everywhere').click( function(){
            dovoEvents.form.whereSetPosition( '', '', ':everywhere', "Everywhere" );
            dovoGMap.resetMyMarker();
            $('#radius-slider').slider("disable");
            return false;
        }).button();
        $('#radius-slider').slider({
            value: $('#radius').val(),
            min: 1,
            max: 100,
            range: "min",
            slide: function( event, ui ) {
                $('#radius').val( ui.value );
                $('#radius-label').text( ui.value );
                dovoGMap.mymarker.circle.setRadius( ui.value*1000 ); // FIXME: oo refactor!
            },
            change: function() {
                $('#page').val(1);
                $('#search').submit();
            }
        });

        // when box
        $( "#datepicker" ).datepicker({
            altField: '#from',
            altFormat: 'yy-mm-dd',
            dateFormat: 'D dd M yy',
            showButtonPanel: true,
            onSelect: function(text, instance) {
                dovoEvents.form.whenChange( text );
            }
        }, $.datepicker.regional['en']
        );
        $('.param, .label', '.when-box').click( dovoEvents.form.whenShow );

        // form
        $("#search")
            .bind( "ajax:beforeSend", dovoEvents.form.beforeSend )
            .bind( "ajax:complete", dovoUI.spinner.stop )
            .bind( "ajax:success", function(event, data, status, xhr) {
                dovoEvents.renderEvents( data, $('#q').siblings('.label'), $('#content-left') );
                dovoEvents.renderTags( data, $('.tagcloud') );
                dovoEvents.renderCallbacks();
            })
            .bind( "ajax:error", function(event, data, status, xhr) {
                console.error('ERROR on form submit! FIXME');
            });
    }

};


$(document).ready(function() {

    dovoGMap.initialize();
    dovoEvents.initialize();

    dovoUI.stickySidebar( '#content-right' );

    // Trigger events at page load and guess #where if empty
    if ( $('#where').val() == '' ) {
        $('#geolocate').click();
    }
    else {
        $('#where').change();
    }

});

