using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using ClarionSimulation;
using VRepProxy;
using VRepProxy.Objects;
using System.Text.RegularExpressions;

namespace ClarionDEMO
{
	class MainClass
	{
		#region properties

		private ClarionAgent agent;
		private static Scene scene;
		private Robot robot;
		private static int nextSide = 0;
		private static int ucounter = 0;
		private static int currentSide = 0;

		#endregion

		#region constructor

		//Dictionary<string, LeafletItem> Consolidatedleaflets;

		//Dictionary<string,int> leafletsTotal = new Dictionary<string,int>();
		//Dictionary<string,int> leafletsCollected = new Dictionary<string,int>();

		public MainClass ()
		{
			Random rnd = new Random ();
			int r = rnd.Next (1, 10);
			nextSide = r > 4 ? (r < 7 ? 1 : 2) : 0;
			Console.WriteLine ("Clarion-VRep Demo V0.4");
			agent = new ClarionAgent ();
			agent.OnNewVisualSensorialInformation += new InputVisualSensorialInformationEventHandler (agent_OnNewVisualSensorialInformationHandler);
			agent.OnNewExternalActionSelected += new OutputActionChunkEventHandler (agent_OnNewExternalActionSelectedHandler);
			scene = new Scene();
			robot = scene.GetRobot ();
			agent.Run ();
		}

		#endregion

		#region Methods
		public static void Main (string[] args)
		{
			new MainClass ();
		}
			
		Perceptions agent_OnNewVisualSensorialInformationHandler ()
		{
			//Console.Out.WriteLine ("Sensorial Info Handler");
			Perceptions perceptions = null;
			if (scene != null) {
				perceptions = robot.GetPerceptions ();

				switch (perceptions.getPerceivedColor ()) {
				case Shape.SHAPE_BLIND:
					Console.Out.WriteLine ("I am blind. ");
					Console.Out.WriteLine ("Cannot connect to the body.");
					Environment.Exit (-1);
					break;
				case Shape.SHAPE_NOTHING:
					Console.Out.WriteLine ("I see " + perceptions.getPerceivedColor ());
					break;
				case Shape.SHAPE_GRAY:
					break;
				case Shape.SHAPE_BLUE:
				case Shape.SHAPE_PINK:
				case Shape.SHAPE_RED:
					Console.Out.WriteLine ("I see " + perceptions.getPerceivedColor () + " color" + " (--> target)");
					break;
				case Shape.SHAPE_GREEN:
				case Shape.SHAPE_WHITE:
				case Shape.SHAPE_YELLOW:
					Console.Out.WriteLine ("I see " + perceptions.getPerceivedColor ()
					+ " color");
					break;
				default:
					Console.Out.WriteLine ("I don't know what I see...");
					break;
				}
			}
			return perceptions;
		}

		void agent_OnNewExternalActionSelectedHandler (ClarionAgentActionType externalAction)
		{
			Thread.CurrentThread.CurrentCulture = new CultureInfo ("en-US");
			if (scene != null) {
				robot.GetWheels ().stop ();	
				switch (externalAction) {
				case ClarionAgentActionType.DO_NOTHING:
					if (nextSide == 0) {
						robot.GetWheels ().RotateRight (0.5);

					} else if (nextSide == 1) {
						robot.GetWheels ().RotateLeft (0.5);
					} else {
						robot.GetWheels ().Move (1);
					}
					if (currentSide != nextSide) ucounter = 0;
					if (ucounter > 30) {
						ucounter = 0;
						Random rnd = new Random ();
				
						int r = rnd.Next (1, 10);
						nextSide = r > 4 ? (r < 8 ? 1 : 2) : 0;
					}
					currentSide = nextSide;
					ucounter++;
					break;
				case ClarionAgentActionType.ROTATE:
					{
						robot.GetWheels ().RotateRight (0.5);
						Random rnd = new Random ();
						int r = rnd.Next (1, 10);
						nextSide = r > 4 ? (r < 7 ? 1 : 2) : 0;
					}
					break;
				case ClarionAgentActionType.MOVE:
					{
						robot.GetWheels ().Move (2);
						Random rnd = new Random ();
						int r = rnd.Next (1, 10);
						nextSide = r > 4 ? (r < 7 ? 1 : 2) : 0;
					}
					break;
				case ClarionAgentActionType.LEFT:
					{
						robot.GetWheels ().Move (1);
						robot.GetWheels ().RotateLeft (1);
						Random rnd = new Random ();
						int r = rnd.Next (1, 10);
						nextSide = r > 4 ? (r < 7 ? 1 : 2) : 0;
					}
					break;
				case ClarionAgentActionType.RIGHT:
					{
						robot.GetWheels ().Move (1);
						robot.GetWheels ().RotateRight (1);
						Random rnd = new Random ();
						int r = rnd.Next (1, 10);
						nextSide = r > 4 ? (r < 7 ? 1 : 2) : 0;
					}
					break;
				case ClarionAgentActionType.BACK:
					{
						robot.GetWheels ().Move (-1);
						robot.GetWheels ().RotateLeft (1);
						Random rnd = new Random ();
						int r = rnd.Next (1, 10);
						nextSide = r > 4 ? (r < 7 ? 1 : 2) : 0;
					}
					break;
				default:
					break;
				}
			}
		}
		#endregion
	}
	
	
}
