public Controller(Model model, View view)
        {
            /* initialize class fields */
            this.model = model;
            this.view = view;
            this.workers = new List<BackgroundWorker>();
            this.cancelled = false;
            this.running = 0;
            this.mapType = Map.MapType.Empty;
            this.nodeEditBackColor = Color.White;
            this.nodeEditForeColor = Color.White;
            this.nodeEditBackColor = Color.White;
            this.nodeEditState = NodeEditState.DISABLED;
            this.nodeEditFinishAgentId = Agent.AgentID.Agent_0;
            this.nodeEditStartAgentId = Agent.AgentID.Agent_0;

            /* initialize the volatile variables */
            tempMapSize = model.getSimulation().get(View.ViewNumericUpDown.MapSize);
            tempPercentWalkable = model.getSimulation().get(View.ViewNumericUpDown.PercentWalkable);
            tempNumberofAgents = model.getSimulation().get(View.ViewNumericUpDown.NumberOfAgents);

            /* generate an empty map without agents */
            generateMapCommon(null, false);
            model.getSimulation().setMapID(0);

            /* mouse event handlers */
            view.getPanelMap().MouseDown += new MouseEventHandler(Controller_MouseDown);
            view.getPanelMap().MouseUp += new MouseEventHandler(Controller_MouseUp);
            view.getPanelMap().MouseClick += new MouseEventHandler(Controller_MouseClick);

            this.mouseDownNodes = new List<Node>();
            mouseDownRunning = false;
            mouseDownBackgroundWorker = new BackgroundWorker();
            mouseDownBackgroundWorker.DoWork += new DoWorkEventHandler(collectNodes_DoWork);
        }
 public int get(View.ViewNumericUpDown type)
 {
     switch (type)
     {
         case View.ViewNumericUpDown.FieldOfView:
             return this.fieldOfView;
         case View.ViewNumericUpDown.MapSize:
             return this.mapSize;
         case View.ViewNumericUpDown.MaxSteps:
             return this.maxSteps;
         case View.ViewNumericUpDown.NumberOfAgents:
             return this.numberOfAgents;
         case View.ViewNumericUpDown.PercentWalkable:
             return this.percentWalkable;
         case View.ViewNumericUpDown.StepDelay:
             return this.stepDelay;
         case View.ViewNumericUpDown.VisualizationDelay:
             return this.visualizationDelay;
         default:
             throw new Exception("simulation type invalid on get");
     }
 }
 private void setVisualization(View.Visualizations visualizations)
 {
     ComboBox cb = view.getComboBox(View.ViewComboBox.Visualizations);
     cb.Enabled = ((View.Visualizations)(cb.SelectedItem) == View.Visualizations.Enabled) ? true : false;
     cb.SelectedItem = visualizations;
     model.getSimulation().setVisualizations(visualizations);
 }
        public void RadioButton_Click(object sender, View.ViewRadioButton eventHandler)
        {
            Debug.WriteLine(eventHandler.ToString() + " Clicked");

            DrawingControl.SuspendDrawing(view.getPanelMap());
            model.getMap().setNodes(Node.Flag.IsVisible, true);
            model.getMap().repaint();
            model.paintAgents();
            DrawingControl.ResumeDrawing(view.getPanelMap());

            switch (eventHandler)
            {
                case View.ViewRadioButton.EditStart:
                    nodeEditStartAgentId = incNodeEditAgentId(model, nodeEditStartAgentId);
                    view.buttonEditStartUpdate(nodeEditBackColor, nodeEditForeColor, "S", true);
                    this.nodeEditState = NodeEditState.START;
                    view.setStatusText("Click Map to Change Agent " + (int)nodeEditStartAgentId + " Start Node");
                    break;
                case View.ViewRadioButton.EditFinish:
                    this.nodeEditState = NodeEditState.FINISH;
                    nodeEditFinishAgentId = incNodeEditAgentId(model, nodeEditFinishAgentId);
                    view.buttonEditFinishUpdate(nodeEditBackColor, nodeEditForeColor, "F", true);
                    view.setStatusText("Click Map to Change Agent " + (int)nodeEditFinishAgentId + " Finish Node");
                    break;
                case View.ViewRadioButton.EditWalkable:
                    this.nodeEditState = NodeEditState.WALKABLE;
                    this.nodeEditBackColor = Color.White;
                    this.nodeEditForeColor = Color.White;
                    view.setStatusText("Click Map to Change Selected Node to Walkable");
                    break;
                case View.ViewRadioButton.EditNonWalkable:
                    this.nodeEditState = NodeEditState.NON_WALKABLE;
                    this.nodeEditBackColor = Color.Gray;
                    this.nodeEditForeColor = Color.Gray;
                    view.setStatusText("Click Map to Change Selected Node to Non-Walkable");
                    break;
            }
        }
        public void NumericUpDown_ValueChanged(object sender, View.ViewNumericUpDown eventHandler)
        {
            NumericUpDown nud = sender as NumericUpDown;
            int value = (int)nud.Value;
            Debug.WriteLine(eventHandler.ToString() + " " + value.ToString());

            switch (eventHandler)
            {
                case View.ViewNumericUpDown.FieldOfView:
                    model.getSimulation().set(View.ViewNumericUpDown.FieldOfView, value);
                    break;
                case View.ViewNumericUpDown.MapSize:
                    tempMapSize = value;
                    view.setStatusText(parametersChanged);
                    break;
                case View.ViewNumericUpDown.PercentWalkable:
                    tempPercentWalkable = value;
                    view.setStatusText(parametersChanged);
                    break;
                case View.ViewNumericUpDown.NumberOfAgents:
                    tempNumberofAgents = value;
                    view.setStatusText(parametersChanged);
                    break;
                case View.ViewNumericUpDown.MaxSteps:
                    model.getSimulation().set(View.ViewNumericUpDown.MaxSteps, value);
                    break;
                case View.ViewNumericUpDown.StepDelay:
                    model.getSimulation().set(View.ViewNumericUpDown.StepDelay, value);
                    break;
                case View.ViewNumericUpDown.VisualizationDelay:
                    model.getSimulation().set(View.ViewNumericUpDown.VisualizationDelay, value);
                    break;
                default:
                    throw new Exception("invalid numeric up/down event handler");
            }
        }
        public void ComboBox_SelectedIndexChanged(object sender, View.ViewComboBox eventHandler)
        {
            ComboBox cb = sender as ComboBox;
            Debug.WriteLine(eventHandler.ToString() + " " + cb.SelectedItem.ToString());

            switch (eventHandler)
            {
                case View.ViewComboBox.AlgorithmType:
                    AlgorithmType algorithmType = (AlgorithmType)cb.SelectedItem;
                    model.getSimulation().setAlgorithmType(algorithmType);
                    view.updateHeuristicMethodItems(algorithmType);
                    ComboBox heuristicMethodComboBox = view.getComboBox(View.ViewComboBox.HeuristicMethod);
                    switch (algorithmType)
                    {
                        case AlgorithmType.Dijkstra:
                            heuristicMethodComboBox.SelectedItem = Node.Method.None;
                            model.getSimulation().setHeuristicMethod(Node.Method.None);
                            break;
                        case AlgorithmType.AStar:
                            heuristicMethodComboBox.SelectedItem = Node.Method.Euclidean;
                            model.getSimulation().setHeuristicMethod(Node.Method.Euclidean);
                            break;
                        default:
                            break;
                    }
                    break;
                case View.ViewComboBox.HeuristicMethod:
                    Node.Method heuristicMethod = (Node.Method)cb.SelectedItem;
                    model.getSimulation().setHeuristicMethod(heuristicMethod);
                    break;
                case View.ViewComboBox.FovMethod:
                    Node.Method fovMethod = (Node.Method)cb.SelectedItem;
                    model.getSimulation().setFieldOfViewMethod(fovMethod);
                    break;
                case View.ViewComboBox.AgentCooperation:
                    View.AgentCooperation agentCooperation = (View.AgentCooperation)cb.SelectedItem;
                    model.getSimulation().setAgentCooperation(agentCooperation);
                    break;
                case View.ViewComboBox.ViewableAgent:
                    Agent.AgentID agentID = (Agent.AgentID)cb.SelectedItem;
                    model.getSimulation().setViewableAgent(agentID);
                    switch (agentID)
                    {
                        case Agent.AgentID.Agent_All:
                            /* set all agents to active */
                            foreach (Agent agent in model.getAgents())
                                agent.setActive(true);
                            break;
                        default:
                            foreach (Agent agent in model.getAgents())
                                agent.setActive(false);
                            Agent a = model.getAgent(agentID);
                            if (a != null)
                                a.setActive(true);
                            break;
                    }
                    break;
                case View.ViewComboBox.Visualizations:
                    View.Visualizations visualizations = ((View.Visualizations)cb.SelectedItem);
                    model.getSimulation().setVisualizations(visualizations);
                    break;
                case View.ViewComboBox.PathPersistence:
                    View.PathPersistence pathPersistence = ((View.PathPersistence)cb.SelectedItem);
                    model.getSimulation().setPersistenceEnabled(pathPersistence);
                    break;
                default:
                    throw new Exception("combo box event handler invalid");
            }
        }
        public void Button_Click(object sender, View.ViewButton eventHandler)
        {
            Debug.WriteLine(eventHandler.ToString() + " Clicked");

            switch (eventHandler)
            {
                case View.ViewButton.RandomMap:
                    mapType = Map.MapType.Random;
                    break;
                case View.ViewButton.EmptyMap:
                    mapType = Map.MapType.Empty;
                    break;
                case View.ViewButton.ResetMap:
                    DrawingControl.SuspendDrawing(view.getPanelMap());
                    model.Reset(true);
                    DrawingControl.ResumeDrawing(view.getPanelMap());
                    break;
            }

            switch (eventHandler)
            {
                case View.ViewButton.RandomMap:
                case View.ViewButton.EmptyMap:
                    /* save the temp variables */
                    model.getSimulation().set(View.ViewNumericUpDown.MapSize, tempMapSize);
                    model.getSimulation().setCellSize(view.PANEL_SIZE / tempMapSize);
                    model.getSimulation().set(View.ViewNumericUpDown.PercentWalkable, tempPercentWalkable);
                    model.getSimulation().set(View.ViewNumericUpDown.NumberOfAgents, tempNumberofAgents);

                    /* generate map */
                    generateMapCommon(null, true);

                    /* initialize the node edit variables */
                    nodeEditStartAgentId = Agent.AgentID.Agent_0;
                    nodeEditFinishAgentId = Agent.AgentID.Agent_0;
                    nodeEditBackColor = model.getAgent(Agent.AgentID.Agent_0).getColor(Agent.ColorType.BackColor);
                    nodeEditForeColor = model.getAgent(Agent.AgentID.Agent_0).getColor(Agent.ColorType.ForeColor);

                    /* update view */
                    view.updateAgentItems();
                    view.getButton(View.ViewButton.Start).Enabled = true;
                    view.getRadioButton(View.ViewRadioButton.EditWalkable).Enabled = true;
                    view.getRadioButton(View.ViewRadioButton.EditNonWalkable).Enabled = true;
                    view.setStatusText("Change Parameters, Edit Map, or Click Start");
                    view.buttonEditStartUpdate(nodeEditBackColor, nodeEditForeColor, "S", true);
                    view.buttonEditFinishUpdate(nodeEditBackColor, nodeEditForeColor, "F", true);
                    break;
                case View.ViewButton.Start:
                    cancelled = false;
                    nodeEditState = NodeEditState.DISABLED;
                    model.getMap().setNodes(Node.Cost.Movement, 0.0);
                    model.getMap().setNodes(Node.Cost.Heuristic, 0.0);
                    model.getMap().setNodes(Node.Cost.Total, 0.0);

                    foreach (Agent agent in model.getAgents())
                    {
                        agent.getMap().setNodes(Node.Cost.Movement, 0.0);
                        agent.getMap().setNodes(Node.Cost.Heuristic, 0.0);
                        agent.getMap().setNodes(Node.Cost.Total, 0.0);
                        agent.getMap().setNodes(Node.Flag.IsWalkable, true);
                        agent.getMap().setNodes(Node.Flag.IsVisible, false);
                        agent.getMap().setNodes(Node.Flag.IsShared, false);
                    }

                    /* update the view */
                    view.setStatusText("");
                    view.getButton(View.ViewButton.Cancel).Enabled = true;
                    view.getButton(View.ViewButton.Start).Enabled = false;
                    view.getButton(View.ViewButton.RandomMap).Enabled = false;
                    view.getButton(View.ViewButton.EmptyMap).Enabled = false;
                    view.controlEnable(false);
                    view.getComboBox(View.ViewComboBox.Visualizations).Enabled = false;

                    DrawingControl.SuspendDrawing(view.getPanelMap());
                    model.Reset(false);
                    DrawingControl.ResumeDrawing(view.getPanelMap());

                    synchronization = new Synchronization(model.getSimulation().get(View.ViewNumericUpDown.NumberOfAgents));

                    /* start the agent background threads */
                    foreach (Agent agent in model.getAgents())
                    {
                        running++;
                        agent.setNode(Agent.NodeType.Current, agent.getNode(Agent.NodeType.Start));
                        agent.setNode(Agent.NodeType.Target, agent.getNode(Agent.NodeType.Finish));
                        agent.getMap().setNodes(Node.Flag.IsPath, false);
                        agent.getNode(Agent.NodeType.Start).setFlag(Node.Flag.IsWalkable, true);
                        agent.getNode(Agent.NodeType.Finish).setFlag(Node.Flag.IsWalkable, true);
                        BackgroundWorker bgw = new BackgroundWorker();
                        bgw.WorkerSupportsCancellation = true;
                        bgw.DoWork += new DoWorkEventHandler(Start_DoWork);
                        bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Start_RunWorkerCompleted);
                        bgw.RunWorkerAsync(agent);
                        workers.Add(bgw);
                    }

                    /* init the parameters for un-applied map changes */
                    view.getNumericUpDown(View.ViewNumericUpDown.MapSize).Value = model.getSimulation().get(View.ViewNumericUpDown.MapSize);
                    view.getNumericUpDown(View.ViewNumericUpDown.PercentWalkable).Value = model.getSimulation().get(View.ViewNumericUpDown.PercentWalkable);
                    view.getNumericUpDown(View.ViewNumericUpDown.NumberOfAgents).Value = model.getSimulation().get(View.ViewNumericUpDown.NumberOfAgents);
                    break;
                case View.ViewButton.Cancel:
                    cancelled = true;
                    view.getButton(View.ViewButton.Cancel).Enabled = false;
                    view.getButton(View.ViewButton.Start).Enabled = true;
                    view.getButton(View.ViewButton.RandomMap).Enabled = true;
                    view.getButton(View.ViewButton.EmptyMap).Enabled = true;
                    view.controlEnable(true);
                    foreach (BackgroundWorker bgw in workers) { bgw.CancelAsync(); }
                    break;
                case View.ViewButton.ExportCsv:
                    StringBuilder result = new StringBuilder();
                    SaveFileDialog saveFileDialog = new SaveFileDialog();
                    saveFileDialog.Filter = "*.csv|";
                    saveFileDialog.OverwritePrompt = true;

                    if (saveFileDialog.ShowDialog() == DialogResult.OK && saveFileDialog.FileName != null)
                    {
                        ListView listView = view.getSimulationListView();

                        /* export the column headers */
                        foreach (ColumnHeader ch in listView.Columns)
                            result.Append(ch.Text + ",");
                        result.AppendLine();

                        /* export the data rows */
                        foreach (ListViewItem listItem in listView.Items)
                        {
                            foreach (ListViewItem.ListViewSubItem lvs in listItem.SubItems)
                                result.Append(lvs.Text + ",");
                            result.AppendLine();
                        }

                        try
                        {
                            File.WriteAllText(saveFileDialog.FileName + ".csv", result.ToString());
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "CSV Export Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    break;
                case View.ViewButton.ClearResults:
                    model.getResults().clear();
                    break;
            }
        }
 public void setVisualizations(View.Visualizations visualizations)
 {
     this.visualizations = visualizations;
 }
 public void setPersistenceEnabled(View.PathPersistence pathPersistence)
 {
     this.pathPersistence = pathPersistence;
 }
 public void setAgentCooperation(View.AgentCooperation agentCooperation)
 {
     this.agentCooperation = agentCooperation;
 }
 public void set(View.ViewNumericUpDown type, int value)
 {
     switch (type)
     {
         case View.ViewNumericUpDown.FieldOfView:
             this.fieldOfView = value;
             break;
         case View.ViewNumericUpDown.MapSize:
             this.mapSize = value;
             break;
         case View.ViewNumericUpDown.MaxSteps:
             this.maxSteps = value;
             break;
         case View.ViewNumericUpDown.NumberOfAgents:
             this.numberOfAgents = value;
             break;
         case View.ViewNumericUpDown.PercentWalkable:
             this.percentWalkable = value;
             break;
         case View.ViewNumericUpDown.StepDelay:
             this.stepDelay = value;
             break;
         case View.ViewNumericUpDown.VisualizationDelay:
             this.visualizationDelay = value;
             break;
         default:
             throw new Exception("simulation type invalid on set");
     }
 }
 public Button getButton(View.ViewButton button)
 {
     switch (button)
     {
         case ViewButton.RandomMap:
             return this.buttonRandomMap;
         case ViewButton.EmptyMap:
             return this.buttonEmptyMap;
         case ViewButton.ResetMap:
             return this.buttonResetMap;
         case ViewButton.Start:
             return this.buttonStart;
         case ViewButton.Cancel:
             return this.buttonCancel;
         case ViewButton.ExportCsv:
             return this.buttonExportCSV;
         case ViewButton.ClearResults:
             return this.buttonClearResults;
         default:
             throw new Exception("invalid button index");
     }
 }