
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

#include "maze.h"
#include "wanderer.h"
#include "path.h"
#include "display.h"

#include "wobject.h"

// For global window: SimpleWindow MyWindow("Wandering",20*0.75, 10*0.75);

void MoveOneRightHandedStep(Wanderer &W, const Maze &M);

int ApiMain() {
	// Open maze data file
	string s;
	cout << "Enter filename: ";
	cin >> s;
	ifstream sin(s.c_str());

	// Initialize maze, wanderer and path
	Maze M(sin);
	Wanderer W(M.GetStart(), East);
	Path WP(W.GetLocation());

	// Initialize and open display windows
	float nr = M.GetNumberRows();
	float nc = M.GetNumberColumns();
	float unit = 0.75;
	SimpleWindow MyWindow("Wandering", nc*unit, nr*unit);
	MyWindow.Open();

	// Define display model
	Display D(MyWindow, M, unit);
	D.SetStepped(W.GetLocation());
	D.DisplayAll();

	// Control wanderer through the maze
	while (W.GetLocation() != M.GetFinish()) {
		// Record current location
		Location prev = W.GetLocation();

		// Make and analyze step
		MoveOneRightHandedStep(W, M);

		if (WP.Contains(W.GetLocation())){
			// Previous location lied in a dead-end corridor
			D.SetErrant(prev);
			D.DisplayLocation(prev);
		}

		// Add step to path and display
		WP.Append(W.GetLocation());
		D.SetStepped(W.GetLocation());
		D.DisplayLocation(W.GetLocation());
	}

	cout << "Type Ctrl-C to remove the display and exit" << endl;
	char AnyChar;
	cin >> AnyChar;

	return 0;
}

void MoveOneRightHandedStep(Wanderer &W, const Maze &M) {
	// Determine current location
	Location p = W.GetLocation();
	int r = p.GetRow();
	int c = p.GetColumn();

	// Determine preferred direction of movement
	Direction d = Clockwise(W.GetDirection()); 

	// Process directions in decreasing order of preference
	do {
		// Examine neighbor in direction d and attempt to 
		// move there
		Location neighbor;
		switch (d) {
			case North:
				neighbor = Location(r-1,c);
				W.LookNorth(M.GetStatus(neighbor));
				W.MoveNorth();
				break;
			case East:
				neighbor = Location(r, c+1);
				W.LookEast(M.GetStatus(neighbor));
				W.MoveEast();
				break;
			case South:
				neighbor = Location(r+1, c);
				W.LookSouth(M.GetStatus(neighbor));
				W.MoveSouth();
				break;
			case West:
				neighbor = Location(r, c-1);
				W.LookWest(M.GetStatus(neighbor));
				W.MoveWest();
				break;
		}
		// Determine nextmost preferred direction
		d = CounterClockwise(d);

		// test to see if we have not moved
	} while (p == W.GetLocation());
}


