// I'm suspicious now of all these descriptions, because the 'open' ones are bogus. On 2009.01.08 I
// discovered that reset->open is not a valid state transition. See the first two 'open' descriptions.
// Both of those are now reset->sclick, but I forgot to update the comments. Maybe go back through
// them some day.

// These are for admin editing mode:
//
// click->open
//	Could be new marker added to map when there are no windows showing
//	Could be existing marker clicked when there are no windows showing
//	Either way, after the sequence, we have an open info window on a standard marker
//
// click->close
//	Existing marker clicked when there is a window showing (full sequence is click->close->open)
//
// close->click
//	Could be destination marker clicked when there is a window showing
//	Could be info window closed (the window that is showing)
//	Could be map clicked (to add new marker) when there is a window showing (full sequence is close->click->open)
//
// open
//	Could be an open that we caused when the user entered marker editing mode (starts from reset state)
//	Could be an open that we caused when the user changed the icon for the marker (starts from reset state)
//	Could be the last transition of map clicked when there is a window showing (started with close->click, above)
//	Could be the last transition of other marker clicked when there is a window showing (started with click->close, above)
//
// close->open
//	User hit 'Apply' on the input form
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// These are for non-admin editing mode:
//
// States: Open, startshow, endshow
// ------------------------
// Open=Start	startshow=0 endshow=0	// IMPOSSIBLE: can't have info window open on start when there's no start
// Open=End		startshow=0 endshow=0	// IMPOSSIBLE: can't have info window open on end when there's no end
// Open=Other	startshow=0 endshow=0	// IMPOSSIBLE: to open info window, user must click, which would have created a start
// Open=Closed	startshow=0 endshow=0	// Initial state
//
// Open=Start	startshow=0 endshow=1	// IMPOSSIBLE: can't have end without a start
// Open=End		startshow=0 endshow=1	// IMPOSSIBLE: can't have end without a start
// Open=Other	startshow=0 endshow=1	// IMPOSSIBLE: can't have end without a start
// Open=Closed	startshow=0 endshow=1	// IMPOSSIBLE: can't have end without a start
//
// Open=Start	startshow=1 endshow=0	// Happens after user selects a start
// Open=End		startshow=1 endshow=0	// IMPOSSIBLE: end doesn't exist
// Open=Other	startshow=1 endshow=0	// IMPOSSIBLE: to open info window on other, user must click, which would have created an end
// Open=Closed	startshow=1 endshow=0	// Happens after user closes info window on start marker
//
// Open=Start	startshow=1 endshow=1	// IMPOSSIBLE: to open start info window, user must click on start, which resets the route
// Open=End		startshow=1 endshow=1	// Happens after user selects an end
// Open=Other	startshow=1 endshow=1	// Happens if user clicks non-route marker
// Open=Closed	startshow=1 endshow=1	// Happens if user closes an info window
//
// Actions:
// Select start from dropdown
// Select end from dropdown
// Click start marker
// Click end marker
// Click non-route marker
// Click 'X' on info window
// Click map
//
// From Open=Closed	startshow=0 endshow=0: 'No info windows open, no start/end markers showing':
// Select start from dropdown
//		sclick->open
// Select end from dropdown	IMPOSSIBLE: I'm going to disable it
//		***** Disable this *****
// Click start marker: 		IMPOSSIBLE: no start marker exists
// Click end marker: 		IMPOSSIBLE: no end marker exists
// Click non-route marker
//		click->sclick->open
// Click 'X' on info window: IMPOSSIBLE: no info window exists
// Click map
//		click->sclick->open
//
// Open=Start startshow=1 endshow=0: 'Info window showing on start marker, no end marker':
// Select start from dropdown
//		close->sclick->open
// Select end from dropdown
//		sclick->close->open
// Click start marker
//		close->click->sclick->markerClick
// Click end marker: 				IMPOSSIBLE: no end marker exists
// Click non-route marker
//		close->click->sclick->open
// Click 'X' on info window
//		close->click->sclick
// Click map
//		close->click->sclick->open
//
// Open=Closed startshow=1 endshow=0: 'No info window showing, start marker present, no end marker':
// Select start from dropdown
// Select end from dropdown
// Click start marker
// Click end marker
// Click non-route marker
// Click 'X' on info window
// Click map
//
// From 'Info window showing on end marker, start and end markers showing':
// 1. User selects item from 'start' dropdown:
//		sclick->close->open
// 2. User clicks the 'x' on the info window:
//		close->click->sclick
// 3. User clicks other map marker:
//		close->click->sclick
// 4. User selects item from 'end' dropdown:
//		close->sclick->open
//
// From 'No info windows open, start/end markers showing':
// 1. User selects item from either dropdown
//		sclick->open
// 2. User clicks map marker that isn't start or end:
//		click->sclick
// 3. User clicks 'end' marker:
//		click->open->sclick->close
// 4. User clicks 'start' marker:
//		click->open->sclick->close
// 5. User clicks map:
//		click->sclick
/*******************/		
//
// 6. Start/end both showing special flags and info window showing on 'end' flag,
//		user clicks map marker that isn't one of the start/end points
//		close->click->sclick
//
// 7. Start/end both showing special flags and info window showing on another flag entirely,
//		user clicks 'x' on info window
//		click->sclick
//
// 8. Start/end both showing special flags and no info window showing, user clicks on
//		'end' flag:
//		click->open->sclick->close
//
// 9. 
// sclick->open
//	Could be an open that we caused when the user used the dropdown menu to select a city (starts from reset state)
function cClickOpenCloseState() {
	var enableLogging = defaultParameter(arguments, 1, false);
	var testMode = defaultParameter(arguments, 2, false);

	this.cClickOpenCloseState = function(enableLogging, testMode) {
		this.mState = null;
		this.mFirstClick = null;
		this.mSecondClick = null;
		this.mDescriptionWindowContents = null;
		this.mLogState = enableLogging;
		this.mTestMode = testMode;

		this.reset();
	}
	
	this.getState = function() {
		return this.mState;
	}
	
	this.reset = function() {
		this.mState = 'reset';
		this.mDescriptionWindowContents = '';
		
		// It's too fucking complicated to think about right now. If I leave these in place, then
		// everything works after the user clicks 'Cancel' on the input form. It was something about
		// the close->click sequence, I think, but I just can't spend any more time on it.
		// It was because 'Apply' results in a close, which results in a reset, but then an open comes
		// after that, and if we reset these at the reset, then we don't know which marker is
		// active.
//		this.mFirstClick = -1;
//		this.mSecondClick = -1;

		if(this.mLogState)
			error_log('reset()->reset');
	}
	
	this.updateState = function(input) {
		var clickedMarkerID = defaultParameter(arguments, 2, -1);
		var descriptionWindowContents = defaultParameter(arguments, 3, '');

		if(this.mTestMode) {
			error_log('Received input ' + input);
			return;
		}
		
		switch(input) {
			case 'click': 	// Real click
			case 'sclick': 	// Simulated click
				this.processClick(input, clickedMarkerID, descriptionWindowContents);
				break;
				
			case 'open':
				this.processOpen();
				break;
				
			case 'close':
				this.processClose();
				break;
				
			default:
				alert('Bad input = ' + input);
				break;
		}
		
		return this.getState();
	}
	
	this.processClick = function(clickType, clickedMarkerID, descriptionWindowContents) {
		var originalState = this.mState;
		switch(this.mState) {
			case 'reset':

			// There is a full close->click sequence, and there is a close->click->open sequence.
			// We can't tell the difference after click. So in any close->click scenario, we
			// end up with state = markerCloseComplete. If we get a click in that state, then we
			// know that we weren't in the close->click->open sequence, but were in the close->click
			// sequence, which ended there but we didn't know it. Now we do know it, and we treat
			// the markerCloseComplete state the same as we would the reset state.
			case 'markerCloseComplete':
				this.mState = 'firstClick';
				this.mFirstClick = clickedMarkerID;
				this.mDescriptionWindowContents = descriptionWindowContents;
				break;
				
			case 'closed':
				this.mState = 'markerCloseComplete';
				this.mFirstClick = clickedMarkerID;
				break;
				
			// When the user is in route-editing mode and there are already markers on the map and
			// he clicks 'Add marker at route end', then we get two simulated clicks. The first one is
			// from setEditMode(), and it contains bogus information about the clicked marker id.
			// The second one is the one that we care about--it's the one from addMarker().
			//
			// When there are no markers on the map and the user clicks 'Add marker at route end', we
			// don't come here, because setEditMode() sees no top marker, and therefore doesn't
			// simulate a click. So we just get the first click from addMarker(), which we handle
			// above in the 'reset' case.
			case 'firstClick':
				this.mState = 'firstClick';
				this.mFirstClick = clickedMarkerID;
				break;
				
			default:
				alert('Bad state transition in processClick(): ' + this.mState + ', id = ' + clickedMarkerID);
				break;
		}

		if(this.mLogState)
			error_log(originalState + '->' + clickType + '->' + this.mState);
	}
	
	this.processOpen = function() {
		var originalState = this.mState;
		switch(this.mState) {
			case 'firstClick':
			case 'markerCloseComplete':
				this.mState = 'markerOpenComplete';
				break;
				
			case 'closed':
				this.mState = 'descriptionSubmitComplete';
				break;
				
			default:
				if(!testMode)
					alert('Bad state transition in processOpen(): ' + this.mState);
				break;
		}

		if(this.mLogState)
			error_log(originalState + '->open->' + this.mState);
	}
	
	this.processClose = function() {
		var originalState = this.mState;
		switch(this.mState) {
			case 'reset':
				this.mState = 'closed';
				break;
				
			case 'firstClick':
				this.mState = 'markerCloseComplete';
				break;
				
			default:
				alert('Bad state transition in processClose(): ' + this.mState);
				break;
		}

		if(this.mLogState)
			error_log(originalState + '->close->' + this.mState);
	}
	
	this.cClickOpenCloseState(enableLogging, testMode);
}
