// 'initialize' is true when initializing the shopping for a list.
// It is used in order to prevent adding multiple
// 'click' event handlers for a control (shop trip, clear trade)
function enableShopping(sourceName, $source, initialize, sourcePage) {
	var xhr;
	var originalCalendarPane = document.createDocumentFragment();
    var originalCalendarPaneNode = null;
    var tsluCalendar = null;

    var $tripsTable = null;
    var $editTradeTripsTable = null;
    var $tradesTable = null;

    switch(sourceName) {
        case 'trips-list':
            $tripsTable = $source;
            if($tripsTable != null)
            {
                appState.shopMode = 'tripShopping';
                $tripsTable.bind('tripSelected', function(e, trip) {
                    showButtons();
                });
            }
            break;

        case 'edit-trade-into-trips-list':
            $editTradeTripsTable = $source;
            if($editTradeTripsTable != null) {
                appState.shopMode = 'editTradeShopping';
                extCalendarPane();

                var constructBehaviour = $editTradeTripsTable.find('td.check').length > 0;
                $('#shop-trip').addClass('hidden');
                $('#clear-temp-trade').addClass('hidden');
                $('#select-pickup-trip').removeClass('hidden');
                $editTradeTripsTable.bind('tripSelected', function(e, trip) {
                    // shop the trip only if the list doesn't support adding/removing trip to a trade
                    if(!constructBehaviour) {
                        var inv = appState.editTrade != null && appState.editTrade.hasIntoTrip(trip);
                        if(appState.tempTrade) {
                            appState.tempTrade.removeAllInto();
                        }
                        else {
                            appState.tempTrade = new Trade();
                        }
                        appState.tempTrade.add('into', trip);
                        updatePanel(false);
                        if(inv)
                            hideButtons(150);
                        else
                            showButtons();
                    }
                });
                $editTradeTripsTable.bind('tripChecked', function(e, data) {
                    addRemoveTrip(data[1], 'into', data[0]);
                });
            }
            break;

        case 'edit-trade-away-trips-list':
            $editTradeTripsTable = $source;
            if($editTradeTripsTable != null) {
                appState.shopMode = 'editTradeShopping';
                extCalendarPane();

                $('#shop-trip').addClass('hidden');
                $('#clear-temp-trade').addClass('hidden');
                $('#select-pickup-trip').removeClass('hidden');
                $editTradeTripsTable.bind('tripChecked', function(e, data) {
                    addRemoveTrip(data[1], 'away', data[0]);
                });
            }
            break;

        case 'edit-trade':
            appState.shopMode = 'editTradeShopping';
            extCalendarPane();
            break;

        case 'trades-list':
            $tradesTable = $source;
            if($tradesTable != null) {
                // save off original calendar pane
                saveCalendar();

                $('#shop-trip').addClass('hidden');
                $('#clear-temp-trade').addClass('hidden');
                $('#create-trade').removeClass('hidden');

                appState.shopMode = 'staticTradeShopping';
                appState.selectedTrip = null;
                $tradesTable.bind('shopTradeRequest', function(e, trade) {
                    appState.tempTrade = trade==null ? null : trade.clone();

                    if(appState.shopMode == 'dynamicTradeShopping' && isPotentialDirectReserveTrade(appState.tempTrade)) {
                        $('#create-trade').removeClass('hidden');
                        showButtons();
                    }
                    else {
                        hideButtons();
                    }

                    updatePanel(false);
                });

                $tradesTable.bind('selectedTradeDeleted', function(e) {
                    appState.tempTrade = null;
                    appState.selectedTrip = null;
                    updatePanel(false);
                });
            }
            break;
    }

    $('body').unbind('potentialTradeUpdated').bind('potentialTradeUpdated', function() {
        updatePanel(false);
    });

	if(initialize) {
		$('#shop-trip a')
            .preventFocusRect()
            .click(function(e) {
			    if (e.button > 1) return;

			    $('#shop-trip').addClass('hidden');
			    $('#clear-temp-trade').removeClass('hidden desabled');

                if(isOnReserve()) {
                    if($tripsTable.find('tr.trip.open.selected'))
                        $('#create-trade.create-reserve-trade').removeClass('hidden');
                }
                else {
                    if($tripsTable.find('tr.trip.selected'))
                        $('#create-trade.create-lineholder-trade').removeClass('hidden');
                }

			    // save off original calendar pane
			    saveCalendar();

			    // start a potential trade with selected trip
                var dir = isOnReserve() ? 'into' : (appState.selectedTrip.mine ? 'away' : 'into');
			    appState.tempTrade = new Trade();
			    appState.tempTrade.add(dir, appState.selectedTrip);

			    updatePanel(!isOnReserve());

			    if (window.pageTracker) pageTracker._trackEvent('CC Lite', 'Shopping - Start');

			    return false;
		    });

		$('#clear-temp-trade a')
            .preventFocusRect()
            .click(function(e) {
			    if (e.button > 1) return;
                if ($(this).parent().hasClass('disabled')) return;

			    $('#shop-trip').removeClass('hidden');
			    $('#clear-temp-trade').addClass('hidden');
                $('#create-trade').addClass('hidden');

                restoreCalendar();

			    if (window.pageTracker) pageTracker._trackEvent('CC Lite', 'Shopping - Clear');
		    });

        $('#create-trade a')
            .preventFocusRect()
            .click(function(e) {
                if (e.button > 1) return;
                if($(this).parent().hasClass('disabled')) return;

                $('#create-trade-progress').removeClass('hidden');
                $('#create-trade a').addClass('loading');
                createTrade();
            });
    }

    $('#select-pickup-trip a')
        .unbind('click')
        .preventFocusRect()
        .click(function(e) {
            if (e.button > 1) return;
            if($(this).parent().hasClass('disabled')) return;

            hideButtons();
            if(armSelectedTrip())
                updatePanel(false);
        });

    // trip checked/uncheked
    function addRemoveTrip(add, type, trip) {
        if(!appState.editTrade) {
            appState.editTrade = new Trade();
        }

        if(add)
            appState.editTrade.add(type, trip);
        else
            appState.editTrade.remove(trip);
        appState.tempTrade = appState.editTrade.clone();
        updatePanel(false);
        hideButtons(150);
    }

    function showButtons() {
        setTimeout(function() {
            buttonsShown = true;
            $('#shop-button-container').slideDown();
        }, 450);
    }

    function hideButtons(timeout) {
        if(typeof(timeout) == "undefined")
            timeout = 450;
        setTimeout(function() {
            buttonsShown = false;
            $('#shop-button-container').slideUp();
        }, timeout);
    }

    function updateCreateTradeBtn() {
        if(!isOnReserve()) {
            var $btna = $('#create-trade a');

            if(appState.tempTrade){
                switch(appState.tempTrade.getTradeDirection())
                {
                    case 'drop':
                        $btna.removeClass('generic-trade pickup').addClass('drop').text('Create drop');
                        break;
                    case 'pickup':
                    case 'crit-pickup':
                        $btna.removeClass('generic-trade drop').addClass('pickup').text('Create pickup');
                        break;
                    case 'trade':
                    default:
                        $btna.removeClass('drop pickup').addClass('generic-trade').text('Create trade');
                        break;
                }
            }
            else {
                $btna.removeClass('drop pickup').addClass('generic-trade').text('Create trade');
            }
        }
    }

    function isPotentialDirectReserveTrade(trade) {
        if (trade == null)
            return false;
        if(!isOnReserve())
            return false;

        var trips = trade.getTradeIntoTrips();
        if(trips.length != 1)   // must have only 1 'into' item
            return false;
        if($("tr #t_" + trips[0].toString() + ".open").length == 0)   //must be open trip
            return false;

        return trade.getTradeDirection() == 'pickup';
    }

    function isOnReserve() {
        return $('#create-trade.create-reserve-trade').length != 0;
    }

    function abortActiveRequest() {
        if (xhr) {
            xhr.abort();
            xhr = null;
        }
    }

    function saveCalendar() {
        var $cp = $('#calendar-pane');
        if($cp.length > 0) {
            originalCalendarPaneNode = $cp[0].cloneNode(true);
            originalCalendarPane.appendChild(originalCalendarPaneNode);
        }
    }

    function restoreCalendar() {
        if(originalCalendarPane.firstChild) {
            var firstChild = originalCalendarPane.firstChild.cloneNode(true);
            var $newPanel = restoreMyTripsState(firstChild);
            $('#calendar-pane').replaceWith($newPanel);

            // re-attach calendar-pane events
            extCalendarPane();

            createCalendarTimeStampUpdater();
        }
    }

	function updatePanel(autoTradeAway) {
        // do nothing if the calendar pane is not available
        var $cp = $('#calendar-pane');
        if($cp.length == 0)
            return;

		abortActiveRequest();

        if(appState.tempTrade == null) {
            restoreCalendar();
        }
        else
        {
		    var params = appState.tempTrade.getParams();
            params = $.extend(params, {shopMode:appState.shopMode});
		    if (autoTradeAway)
                params = $.extend(params, {autoTradeAway:'yes'});

		    $('#clear-temp-trade a').addClass('loading');

		    xhr = $.ajax({
			    type: 'GET',
			    url: 'calendar-pane.php',
			    data: params,
			    timeout: 15000,
			    success: function(data, textStatus) {
				    xhr = null;
				    $('#clear-temp-trade a').removeClass('loading');
                    var $newPanel = restoreMyTripsState(data);
				    var $oldPanel = $('#calendar-pane').replaceWith($newPanel);

				    if (window.calendarPaneTempTrade) {
					    var tt = window.calendarPaneTempTrade, newTrade = new Trade();
					    for (var i=0; i<tt.tradeItems.length; i++) {
						    var ti = tt.tradeItems[i], trip = new Trip();
						    trip.id = ti.trip.id;
						    trip.date = ti.trip.date;
						    trip.month = ti.trip.month;
						    trip.dom = ti.trip.dom;
						    trip.eqp = ti.trip.fleet;
						    trip.pos = ti.trip.seat.replace(/\//g,'');

						    newTrade.add(ti.type, trip);
					    }
					    appState.tempTrade = newTrade;
				    }
                    updateCreateTradeBtn();

				    extCalendarPane();
                    createCalendarTimeStampUpdater($newPanel);
			    },
			    error: function(xhr2, textStatus, errorThrown) {
				    xhr = null;
				    $('#clear-temp-trade a').removeClass('loading');

				    alert('error loading calendar pane for shopped trip');
			    }
		    });
        }
	}

    function restoreMyTripsState(data) {
        var $calPane = $(data);
        var val = getCookie('expandedCalPaneTrips');
        if(val == "true") {
            var $a = $calPane.find('#extras a.toggle-my-trips');
            if($a.length > 0) {
                var $tripsCont = $($a[0]).next();
                if($tripsCont) {
                    $tripsCont.removeClass('hidden');
                    $a.text('Hide My Trips')
                }
            }
        }
        return $calPane;
    }

	function extCalendarPane($cp) {
		$cp = calendarPane($cp);

		// handle remove item buttons for individual trade items
		$('#scratchpad .remove')
			.preventFocusRect()
			.click(function(e) {
				if (e.button > 1) return;
				abortActiveRequest();

				var $ti = $(this).parent();
				var m = /^ti_(away|into)_(.*)$/i.exec($ti.attr('id'));
				var type = m[1], trip = Trip.fromString(m[2]);
				appState.tempTrade.remove(trip);

				$ti.remove();

				if (appState.tempTrade.tradeItems.length == 0) {
					$('#clear-temp-trade a').click();
				} else {
					updatePanel();
					if (window.pageTracker) pageTracker._trackEvent('CC Lite', 'Shopping - Remove Trip');
				}
			});

		$('#trade-buttons .button')
			.mousedown(function(e) {
				if (e.button > 1) return;
				$(this).addClass('mousedown');
				return false;
			})
			.mouseup(function(e) {
				if (e.button > 1) return;
				$(this).removeClass('mousedown');
			})
			.bind('mouseleave', function(e) {
				if (e.button > 1) return;
				$(this).removeClass('mousedown');
			});

		$('#add-selected-trip')
			.click(function(e) {
				if (e.button > 1) return;

				var $btn = $(this);
				if (!$btn.hasClass('disabled')) {
					$btn.addClass('disabled');
                    var dir = isOnReserve() ? 'into' : (appState.selectedTrip.mine ? 'away' : 'into');
					appState.tempTrade.add(dir, appState.selectedTrip);
					updatePanel();
					if (window.pageTracker) pageTracker._trackEvent('CC Lite', 'Shopping - Add Selected Trip');
				}
			});

		$('#add-my-trip')
			.click(function(e) {
				if (e.button > 1) return;

				//$(this).toggleClass('active');
				$('#add-my-trip-dropdown-list').toggle();
			});

		$('#add-my-trip-dropdown-list .mytrip')
			.click(function(e) {
				if (e.button > 1) return;

				$('#add-my-trip').click(); // close dropdown
				var m = /^mytrip_(.*)$/i.exec($(this).attr('id'));
				var trip = Trip.fromString(m[1]);
				appState.tempTrade.add('away', trip);
				updatePanel();

				if (window.pageTracker) pageTracker._trackEvent('CC Lite', 'Shopping - Add My Trip');
			});

		$cp.find('#calc-legality').click(function(e) {
			if (e.button > 1) return;

			var $lc = $('#legality-container');
			$lc	.empty()
				.addClass('loading')
				.load($(this).attr('href'), function() {
					$lc.removeClass('loading');
					$lc.find('.illegality').cluetip(window.cluetipOptions);
                    $lc.find('.warning').cluetip(window.cluetipOptions);
				});
			return false;
		});

		// for now, automatically calculate legality
		$cp.find('#calc-legality').click();
	}

    function createCalendarTimeStampUpdater($calPane){
        if($calPane && originalCalendarPaneNode) {
            var $foundEl = $calPane.find('div.lastupdated');
            if($foundEl.length > 0) {
                var $luFrom = $($foundEl[0]);
                var $originalCalendarPaneNode = $(originalCalendarPaneNode);
                $foundEl = $originalCalendarPaneNode.find('div.lastupdated');
                if($foundEl.length > 0) {
                    var $luTo = $($foundEl[0]);
                    TimestampUpdater.setLastUpdated($luFrom, $luTo);
                }
            }
        }

        if(window.appState.timestampUpdater) {
            window.appState.timestampUpdater.syncTimestamp('#calendar-pane div.lastupdated');
        }
    }

    function createTrade() {
        var $cp = $('#calendar-pane');
        if($cp.length == 0)
            return;

        // prevent problems with crating a trade multiple times by using "prev/next page" buttons
        var params = appState.tempTrade.getParams();
        params['lastPage'] = sourcePage; // window.location.href
        var $form = $('<form action="mytrades.php?edit=new" method="post"></form>').appendTo($cp);
        for(var paramName in params) {
            $form.append('<input type="hidden" name="' + paramName + '" value="'+ params[paramName] + '"/><')
        }
        $form.submit();

        //location.href = 'mytrades.php?edit=new&' + appState.tempTrade.getUrlParams();
    }
}
