if(typeof Tunisia == 'undefined' || !Tunisia) var Tunisia = {};

/**
 * Google map for Tunisia
 * @author Tsuyoshi Saito <tsuyoshi@on-idle.com>
 * @version 1.0
 */
Tunisia.ItineraryEditor = (function(){
    // private vars
    var _options;
    var _itinerary;
    var _data;
    var _markers;
    var _timeline = {
        shown: 3
    }
    var _currentMarker = {}
    var _itineraryItems = [];
    
    /**
     * Get marker object from google markers
     * @param {Object} id
     */
    var getMarkerById = function(id) {
        var marker;
        $(Map.google.markers()).each(function(i, item){
            if (item.id == id) {
                marker = item;
            }
        });
        return marker;
    }
    
    /**
     * Update itinerary my items counter
     * @param {Object} number
     */
    var updateCounter = function(number) {
        $('.my-tunisia-itinerary-item-counter').html(number);
    }
    
    /**
     * Set itinerary repository panes
     */
    var setItineraryData = function() {
        // Itinerary title
        $('.itinerary-data-item').each(function(i, item){
            var rel = $(item).attr('rel').split(':');
            var id = rel[1];
            var marker = getMarkerById(id);
            if (marker) {
                $(item).click(function(event){
                    event.preventDefault();
                    GEvent.trigger(marker, "click");
                }).hover(function(){
                    GEvent.trigger(marker, "mouseover");
                }, function(){
                    GEvent.trigger(marker, "mouseout");
                });
            } else {
                $(item).click(function(event){
                    event.preventDefault();
                    InfoWindow = new Map.InfoWindow();
                    var w = InfoWindow.open(_data.itineraryItems[id]);
                });
            }
        });
        // Date picker
        if(_itinerary && _itinerary.start_date && _itinerary.end_date) {
            var startDate = _itinerary.start_date.split("-");
            var endDate = _itinerary.end_date.split("-");
            $('.itinerary-data-add-to-timeline').datepicker({ 
                showOn: 'button',
                buttonText: 'Add',
                buttonImageOnly: true,
                buttonImage: _options.itineraryAddImagePath,
                showButtonPanel: true,
                dateFormat: 'yy-mm-dd',
                showAnim: 'fadeIn',
                minDate: new Date(startDate[0], startDate[1] - 1, startDate[2]),
                maxDate: new Date(endDate[0], endDate[1] - 1, endDate[2]),
                onSelect: function(dateText) {
                    add($(this), dateText);
                }
            });
        }
        // Remove buttons
        $('.itinerary-remove').click(function(event){
            event.preventDefault();
            if (confirm('Are you sure?')) {
                window.location = $(this).attr('href');
            }
        });
    }
    
    /**
     * Ajax call for removing itinerary item data
     * @param {Object} anchor
     */
    var removeItineraryItem = function(anchor) {
        var parent = $(anchor).parent().parent();
        $.ajax({
            url: $(this).attr('href'),
            type: 'get',
            dataType: 'json',
            cache: false,
            beforeSend: function(){
                $('#loading').vCenter().fadeIn();
            },
            error: function(){
                $('#loading').fadeOut();
                alert('Error loading data.....');
            },
            success: function(data){
                $('#loading').fadeOut();
                if (data.success) {
                    parent.fadeOut('slow');
                    updateCounter(data.total);
                    if (Map.google.markers()) {
                        refreshMarkers();
                    }
                }
                else {
                    alert('Failed to remove, please try again');
                }
            }
        });
    }
    
    /**
     * Load json data for itinerary page
     */
    var loadData = function() {
        var url = _options.url.data;
        if (url) {
            $.ajax({
                url: url,
                type: 'get',
                dataType: 'json',
                cache: false,
                beforeSend: function(){
                    $('#loading').vCenter().fadeIn();
                },
                error: function(){
                    $('#loading').fadeOut();
                    alert('Error loading data.....');
                },
                success: function(data){
                    $('#loading').fadeOut();
                    onDataLoaded(data);
                }
            });
        }
    }
    
    /**
     * Call back when itineray json data loaded
     * @param {Object} data
     */
    var onDataLoaded = function(data) {
        _itinerary = data.itinerary;
        _data = data;
        $.each(_data.itineraryItineraryItems, function(i, item){
            _itineraryItems.push({
                id: item.id,
                item_id: item.itinerary_item_id
            });
        });
        refreshMarkers();
        setItineraryData();
        seTimelineControl();
        setTimelineData();
        setTimelineNotes();
    }
    
    /**
     * Set timeline data on load
     */
    var setTimelineData = function() {
        // Activities and Accommodations
        var data = _data.itineraryItineraryItems;
        $.each(data, function(i, item){
            $('.day').each(function(j, day){
                var date = $(this).attr('id').split('_')[1];
                if(date == item.timeline_date) {
                    var o = _data.itineraryItems[item.itinerary_item_id];
                    var r = item;
                    if (o) {
                        var link = createTimelineItem(o, r);
                        if (o.object == 'Activity') {
                            $(this).find('div.what-to-do div.row-content').append(link);
                        }
                        if (o.object == 'Accommodation') {
                            $(this).find('div.where-to-stay div.row-content').append(link);
                        }
                    }
                }
            });
        });
        // Events
        $.each(_data.events, function(i, item){
            $('.day').each(function(j, day){
                var date = $(this).attr('id').split('_')[1];
                if(date >= item.start_date && date <= item.end_date) {
                    var link = createTimelineEventItem(item);
                    $(this).find('div.events div.row-content').append(link);
                }
            });
        });
        // Paginate timeline items
        paginateTimelineItems();
    }
    
    /**
     * Set timeline note data
     */
    var setTimelineNotes = function() {
        // Form for editting notes
        $('div.row.notes').click(function(event){
            event.preventDefault();
            var textHolder = $(this).find('div.row-content');
            var options = {
                windowTemplate:'<div id="modal-window" style="display:none;background:#FFF;padding:10px;"><div id="modal-window-content"></div></div>'
            }
            var options = {}
            var day = $(this).parent();
            var dayId = $(day).attr('id');
            var date = dayId.replace('day_', '');
            var mw = new ModalWindow(options);
            var url = _options.url.edit_notes + '/' + date;
            mw.showAjax(url, {
                'size': '500x300'
            }, function(){
                $('#edit-itinerary-notes').submit(function(event){
                    event.preventDefault();
                    var url = $(this).attr('action') + '/' + date;
                    $.ajax({
                        url: url,
                        type: 'post',
                        dataType: 'json',
                        data: $(this).serialize(),
                        cache: false,
                        beforeSend: function(){
                            $('#loading').vCenter().fadeIn();
                        },
                        error: function(){
                            $('#loading').fadeOut();
                            alert('Error loading data.....');
                        },
                        success: function(data){
                            $('#loading').fadeOut();
                            if (data.success) {
                                if(data.notes) {
                                    $(textHolder).html(data.notes);  
                                }
                                mw.close();
                            } else {
                                alert('Failed to update notes, please try again');
                            }
                        }
                    });
                });
            });
        });
    }
    
    /**
     * Create timeline item and sets callback events
     * @param {Object} itineraryItemData
     */
    var createTimelineItem = function(itineraryItemData, itineraryItineraryItemData) {
        var o = itineraryItemData;
        var r = itineraryItineraryItemData;
        var m;
        var removeLink = $('<a class="timeline-item-remove">Remove</a>').click(function(event){
            event.preventDefault();
            var parent = $(this).parent();
            $.ajax({
                url: _options.url.remove + '/' + r.id,
                type: 'get',
                dataType: 'json',
                cache: false,
                beforeSend: function(){
                    $('#loading').vCenter().fadeIn();
                },
                error: function(){
                    $('#loading').fadeOut();
                    alert('Error loading data.....');
                },
                success: function(data){
                    $('#loading').fadeOut();
                    if (data.success) {
                        parent.fadeOut('slow');
                        refreshMarkers();
                    } else {
                        alert('Failed to remove, please try again');
                    }
                }
            });
        });
        var titleLink = $('<a class="timeline-item-title"></a>').html(o.title_short).attr({
            title: o.title
        }).click(function(event){
            event.preventDefault();
            GEvent.trigger(getMarkerById(o.id), "click");
        }).hover(function(){
            GEvent.trigger(getMarkerById(o.id), "mouseover");
        }, function(){
            GEvent.trigger(getMarkerById(o.id), "mouseout");
        });
        return $('<div class="timeline-item-links clearfix"></div>').append(removeLink).append(titleLink);
    }
    
    var createTimelineEventItem = function(data) {
        var o = data;
        var titleLink = $('<a class="timeline-item-title"></a>').html(o.title_short).attr({
            title: o.title
        }).click(function(event){
            event.preventDefault();
            GEvent.trigger(getMarkerById(o.id), "click");
        }).hover(function(){
            GEvent.trigger(getMarkerById(o.id), "mouseover");
        }, function(){
            GEvent.trigger(getMarkerById(o.id), "mouseout");
        });
        return $('<div class="timeline-item-links clearfix"></div>').append(titleLink);
    }
    
    /**
     * Add itinerary item reference to itinerary
     * @param {Object} obj
     * @param {Object} dateText
     */
    var add = function(obj, dateText) {
        var rel = $(obj).parent().parent().find('a.itinerary-data-item').attr('rel');
        var options = rel.split(':');
        var id = options[1];
        var itineraryItem = _data.itineraryItems[id];
        var url = _options.url.add;
        $.ajax({
            url: url,
            data: {
                'data[ItineraryItineraryItem][date]': dateText,
                'data[ItineraryItineraryItem][itinerary_item_id]': itineraryItem.id
            },
            type: 'post',
            dataType: 'json',
            cache: false,
            beforeSend: function(){
                $('#loading').vCenter().fadeIn();
            },
            error: function(){
                $('#loading').fadeOut();
                alert('Error loading data.....');
            },
            success: function(data){
                $('#loading').fadeOut();
                if (data.success == true) {
                    _itineraryItems.push({
                        id: data.newId,
                        item_id: itineraryItem.id
                    });
                    $('.day').each(function(i, item){
                        var date = $(this).attr('id').split('_')[1];
                        if (date == dateText) {
                            moveTimelineTo(i);
                            var o = _data.itineraryItems[itineraryItem.id];
                            if (o) {
                                var link = createTimelineItem(o);
                                if (o.object == 'Activity') {
                                    $(this).find('div.what-to-do div.row-content').append(link);
                                }
                                if (o.object == 'Accommodation') {
                                    $(this).find('div.where-to-stay div.row-content').append(link);
                                }
                            }
                        }
                    });
                    refreshMarkers();
                    paginateTimelineItems();
                }
            }
        });
    }
    
    /**
     * Refresh google markers
     */
    var refreshMarkers = function() {
        Map.google.clearMarkers();
        var markers = [];
        $.each(_data.itineraryItems, function(i, item){
            var point = Map.google.getPoint(item.lat, item.lng);
            $.extend(item, {
                active: false
            });
            var addToMarker = false;
            $.each(_itineraryItems, function(j, item2){
                if(item.id == item2.item_id) addToMarker = true;
            });
            if (addToMarker) {
                var marker = Map.google.createMarker(point, item, icon({
                    src: item.icon.src
                }));
                // Add marker event
                GEvent.addListener(marker, 'mouseover', function(){
                    onMarkerMouseover(this);
                });
                GEvent.addListener(marker, 'mouseout', function(){
                    onMarkerMouseout(this);
                });
                GEvent.addListener(marker, 'click', function(){
                    onMarkerClick(this);
                });
                markers.push(marker);
            }
        });
        $.each(_data.events, function(i, item) {
            var point = Map.google.getPoint(item.lat, item.lng);
            $.extend(item, {
                active: true
            });
            var marker = Map.google.createMarker(point, item, icon({
                src: item.icon.src
            }));
            // Add marker event
            GEvent.addListener(marker, 'mouseover', function(){
                onMarkerMouseover(this);
            });
            GEvent.addListener(marker, 'mouseout', function(){
                onMarkerMouseout(this);
            });
            GEvent.addListener(marker, 'click', function(){
                onMarkerClick(this);
            });
            markers.push(marker);
        });
        Map.google.addMarkers(markers);
    }
    
    /**
     * Callback for on marker click
     * @param {Object} marker
     */
    var onMarkerClick = function(marker) {
        $(Map.google.markers()).each(function(i, item){
            item.active = false;
        });
        marker.active = true;
        Map.google.panTo(marker.lat, marker.lng);
        _infoWindow = new Map.InfoWindow();
        var infoWindow = _infoWindow.open(marker);
    }
    
    /**
     * Callback for on marker hover
     * @param {Object} marker
     */
    var onMarkerMouseover = function(marker){
        $('#gmarker-label').remove();
        var id = '#mtgt_' + marker.id;
        _currentMarker.zindex = GOverlay.getZIndex(marker.getPoint().lat());
        $(id).css('z-index', 500003);
        var pos = $(id).position();
        var label = $('<span id="gmarker-label"></span>').css({
            'position': 'absolute',
            'z-index': 500001,
            'top': pos.top + 'px',
            'left': pos.left + 11 + 'px'
        }).html(marker.title);
        $(id).parent().append(label);
    }
    
    /**
     * Callback for on marker mouseout
     * @param {Object} marker
     */
    var onMarkerMouseout = function(marker){
        $('#gmarker-label').remove();
        var id = '#mtgt_' + marker.id;
        $(id).css('z-index', _currentMarker.zindex);
    }
    
    /**
     * Set timeline control links
     */
    var seTimelineControl = function() {
        _timeline.days = $('.itinerary-calendar-timeline div.day').length;
        _timeline.max = _timeline.days - _timeline.shown;
        _timeline.current = 0;
        $('.itinerary-timeline-pager-prev a').click(function(event){
            event.preventDefault();
            moveTimeline('-', 1);
        });
        $('.itinerary-timeline-pager-next a').click(function(event){
            event.preventDefault();
            moveTimeline('+', 1);
        });
    }
    
    /**
     * Move timeline back and forward
     * @param {Object} direction
     * @param {Object} step
     */
    var moveTimeline = function(direction, step) {
        var index = (direction == '+') ? _timeline.current + step : _timeline.current - step;
        setTimelineIndex(index);
        animateTimeline();
    }
    
    /**
     * Move timeline to certain index(position)
     * @param {Object} index
     */
    var moveTimelineTo = function(index) {
        setTimelineIndex(index);
        animateTimeline();
    }
    
    /**
     * Set timeline current index
     * @param {Object} index
     */
    var setTimelineIndex = function(index) {
        _timeline.current = index;
        if (_timeline.current < 0) {
            _timeline.current = 0;
        }
        if (_timeline.current > _timeline.max) {
            _timeline.current = _timeline.max;
        }
    }
    
    /**
     * Animate timeline sliding
     */
    var animateTimeline = function() {
        if (_timeline.days > _timeline.shown) {
            var w = $('.itinerary-calendar-timeline .day').width() + 1;
            var pos = $('.itinerary-calendar-timeline').position();
            $('.itinerary-calendar-timeline').animate({
                left: -(w * _timeline.current) + 'px'
            }, 'slow');
        }
    }
    
    var paginateTimelineItems = function() {
        $('div.row-content').each(function(){
            var currentPage = 0;
            var perPage = 3;
            var $table = $(this);
            var numRows = $table.find('div.timeline-item-links').length;
            var numPages = Math.ceil(numRows / perPage);
            
            if(numPages > 1) {
                $table.find('div.timeline-item-links').show()
                .slice(0, currentPage * perPage).hide().end()
                .slice(((currentPage + 1) * perPage - 1) + 1).hide().end();
                
                if($table.parent().find('.row-content-pager')) {
                    $table.parent().find('.row-content-pager').remove();
                }
                
                var pager = $('<div class="row-content-pager"></div>');
                
                for(var i = 0; i < numPages; i++) {
                    $('<span class="page"></span>').html(i + 1).bind('click', { 'newPage': i }, function(event){
                        event.preventDefault();
                        currentPage = event.data['newPage'];
                        $table.find('div.timeline-item-links').show()
                        .slice(0, currentPage * perPage).hide().end()
                        .slice(((currentPage + 1) * perPage - 1) + 1).hide().end();
                    }).appendTo(pager);
                }
                
                $table.parent().append(pager);
            }
        });
    }
    
    // Public methods
    return {
        init: function(options) {
            var map = Map.google;
            map.setup();
        },
        
        setup: function(options) {
            _options = options;
            loadData();
        }
    }
}());