/// <summary>
 /// Commodity controls are created and deleted dynamically therefore these controls
 /// are binded through different class called CommoditiesEntryModel.
 /// Each row of controls has new instance of EntryModel class.
 /// Every new commodity is added to CommodityList
 /// </summary>
 /// <param name="parameter"></param>
 private void _AddNewCommodity(object parameter)
 {
     CommoditiesEntryViewModel CommView = new CommoditiesEntryViewModel();
     CommView.CombList = _VList;
     CommView.ParentList = CommodityList;
     CommodityList.Add(CommView);
 }
        /// <summary>
        /// Commodity controls are created and deleted dynamically therefore these controls
        /// are binded through different class called CommoditiesEntryModel.
        /// Each row of controls has new instance of EntryModel class.
        /// Every new commodity is added to CommodityList
        /// </summary>
        /// <param name="parameter"></param>
        private void _AddNewCommodity(object parameter)
        {
            CommoditiesEntryViewModel CommView = new CommoditiesEntryViewModel();

            CommView.CombList   = _VList;
            CommView.ParentList = CommodityList;
            CommodityList.Add(CommView);
        }
        private void _OpenDefaultGraph()
        {
            string[] lines = null;
            // Create an open file dialog box and only show *.grf files.
            try
            {
                OpenFileDialog openDlg = new OpenFileDialog();
                openDlg.Filter = "Graph File |*.grf";
                //read all lines of file
                if (true == openDlg.ShowDialog())
                {
                    lines = File.ReadAllLines(openDlg.FileName);

                    _openedFileName = openDlg.FileName;

                    Graph = new NetGraph(true);

                    //following block of code try to read the file and create graph
                    // to fully understant this code please read the graph file in notepad

                    string[] IDs = lines[0].Split(',');

                    foreach (string id in IDs)
                    {
                        int currID = int.Parse(id);
                        _VList.Add(currID);
                        Graph.AddVertex(new NetVertex(currID));
                    }
                    _IDCount = _VList.Count;

                    string[] edges = lines[1].Split(',');
                    string[] temp;
                    int      idTo, idFrom;
                    int      from = 0, to = 0;
                    int      count = Graph.VertexCount;
                    foreach (string part in edges)
                    {
                        temp   = part.Split('-');
                        idFrom = int.Parse(temp[0]);
                        idTo   = int.Parse(temp[1]);

                        for (int i = 0; i < count; i++)
                        {
                            if (Graph.Vertices.ElementAt(i).ID == idFrom)
                            {
                                from = i;
                            }
                            if (Graph.Vertices.ElementAt(i).ID == idTo)
                            {
                                to = i;
                            }
                        }

                        //   _AddNewGraphEdge(_existingVertices[--idTo], _existingVertices[--idFrom]);
                        _AddNewGraphEdge(Graph.Vertices.ElementAt(from), Graph.Vertices.ElementAt(to));
                    }
                    string[] commodities = lines[2].Split(',');
                    if (commodities.Length > 0)
                    {
                        CommodityList.RemoveAt(0);
                    }
                    foreach (string part in commodities)
                    {
                        temp = part.Split('-');
                        from = int.Parse(temp[0]);
                        to   = int.Parse(temp[1]);
                        if (from != to)
                        {
                            CommoditiesEntryViewModel cvm = new CommoditiesEntryViewModel();
                            cvm.OriginID      = from;
                            cvm.DestinationID = to;
                            cvm.DemandVal     = int.Parse(temp[2]);
                            cvm.CombList      = _VList;
                            cvm.ParentList    = CommodityList;
                            CommodityList.Add(cvm);
                        }
                    }
                    NotifyPropertyChanged("Graph");
                }
            }
            catch (IOException e)
            {
                ExceptionMessage.Show("Could Not Open File\n" + e.ToString());
                Graph = null;
            }
            catch (Exception ex)
            {
                ExceptionMessage.Show("Something wrong with the Data in the File\n" + ex.ToString());
                Graph = null;
            }
        }
        /// <summary>
        /// This method takes graph file data for networkx graph and
        /// creates vertexes, edges. It also creates random commodities with
        /// valid paths.
        /// </summary>
        /// <param name="lines">graph file text</param>
        private void _DrawGraphWithCommodities(string [] lines)
        {
            int             CommodityNum = this._NumberOfCommoditiesVal;
            int             MinComm = this._MinimumDemandVal;
            int             MaxComm = this._MaximumDemandVal + 1;
            int             nodeID = 0;
            bool            CommoditySet = false;
            List <int>      Origins = new List <int>();
            List <int>      Destinations = new List <int>();
            List <float>    Demands = new List <float>();
            int             OriginID = 0, DestID = 0;
            float           demand   = 0;
            SortedSet <int> nodeList = new SortedSet <int>();
            //   HashSet<int> nodeList = new HashSet<int>();
            HashSet <int> edgeOutNodes = new HashSet <int>();
            Random        random       = new Random();
            Dictionary <int, LinkedList <int> > EdgeMap = new Dictionary <int, LinkedList <int> >();

            Graph = new NetGraph(true);
            try
            {
                foreach (string line in lines) //create and add vertex to the graph
                {
                    string[] IDs = line.Split(' ');

                    if (int.TryParse(IDs[0], out nodeID))
                    {
                        foreach (string id in IDs)
                        {
                            int currID = int.Parse(id);
                            if (nodeList.Add(currID))
                            {
                                // _VList.Add(currID);
                                Graph.AddVertex(new NetVertex(currID));
                            }
                        }
                    }
                }
                for (int i = 0; i < nodeList.Count; i++)
                {
                    _VList.Add(nodeList.ElementAt(i));
                }
                this._IDCount = this._VList.Count();
                int  from = 0, to = 0, curID = 0;
                int  count = Graph.VertexCount;
                bool valid = true;
                //create edges, and keep record of vertex with edges going out for each valid vertex
                foreach (string line in lines)
                {
                    string[] IDs = line.Split(' ');

                    if (int.TryParse(IDs[0], out nodeID))
                    {
                        EdgeMap.Add(nodeID, new LinkedList <int>());
                        for (int j = 1; j < IDs.Length; j++)
                        {
                            curID = int.Parse(IDs[j]);
                            valid = true;
                            if (EdgeMap.ContainsKey(curID))
                            {
                                foreach (int id in EdgeMap[curID])
                                {
                                    if (id == nodeID)
                                    {
                                        valid = false;
                                    }
                                }
                            }
                            if (valid)
                            {
                                edgeOutNodes.Add(nodeID);
                                EdgeMap[nodeID].AddLast(curID);
                                for (int i = 0; i < count; i++)
                                {
                                    if (Graph.Vertices.ElementAt(i).ID == nodeID)
                                    {
                                        from = i;
                                    }
                                    if (Graph.Vertices.ElementAt(i).ID == curID)
                                    {
                                        to = i;
                                    }
                                }
                                this._AddNewGraphEdge(Graph.Vertices.ElementAt(from), Graph.Vertices.ElementAt(to));
                            }
                        }
                    }
                }

                //commodity is choosed at random, if that commodity does not already exist
                //check if it has valid path. if it exists then just add demand to it.

                for (int i = 0; i < _NumberOfCommoditiesVal; i++)
                {
                    CommoditySet = false;
                    while (!CommoditySet)
                    {
                        OriginID = random.Next(0, edgeOutNodes.Count);
                        OriginID = edgeOutNodes.ElementAt(OriginID);
                        DestID   = random.Next(0, nodeList.Count);
                        DestID   = nodeList.ElementAt(DestID);
                        demand   = random.Next(MinComm, MaxComm);

                        for (int j = 0; j < Origins.Count; j++)
                        {
                            if (Origins[j] == OriginID && Destinations[j] == DestID)
                            {
                                CommoditySet = true;
                                Demands[j]  += demand;
                                break;
                            }
                        }

                        if (CommoditySet)
                        {
                            break;
                        }
                        this._path = null;
                        if (this._HasPath(OriginID, DestID, nodeList.Count, EdgeMap))
                        {
                            // this._GetSimulationEdges(OriginID, DestID);
                            Origins.Add(OriginID);
                            Destinations.Add(DestID);
                            Demands.Add(demand);
                            CommoditySet = true;
                        }
                    }
                }

                if (Origins.Count > 0)
                {
                    CommodityList.Remove(CommodityList.ElementAt(0));
                }
                for (int i = 0; i < Origins.Count; i++)
                {
                    CommoditiesEntryViewModel cvm = new CommoditiesEntryViewModel();
                    cvm.OriginID      = Origins[i];
                    cvm.DestinationID = Destinations[i];
                    cvm.DemandVal     = Demands[i];
                    cvm.CombList      = _VList;
                    cvm.ParentList    = CommodityList;
                    CommodityList.Add(cvm);
                }

                NotifyPropertyChanged("Graph");
            }
            catch (Exception ex)
            {
                ExceptionMessage.Show("Something wrong with the Data in the File\n" + ex.ToString());
                Graph = null;
            }
        }
        /// <summary>
        /// This method takes graph file data for networkx graph and 
        /// creates vertexes, edges. It also creates random commodities with
        /// valid paths. 
        /// </summary>
        /// <param name="lines">graph file text</param>
        private void _DrawGraphWithCommodities(string [] lines)
        {
            int CommodityNum = this._NumberOfCommoditiesVal;
            int MinComm = this._MinimumDemandVal;
            int MaxComm = this._MaximumDemandVal + 1;
            int nodeID = 0;
            bool CommoditySet = false;
            List<int> Origins = new List<int>();
            List<int> Destinations = new List<int>();
            List<float> Demands = new List<float>();
            int OriginID = 0, DestID = 0;
            float demand = 0;
            SortedSet<int> nodeList = new SortedSet<int>();
             //   HashSet<int> nodeList = new HashSet<int>();
            HashSet<int> edgeOutNodes = new HashSet<int>();
            Random random = new Random();
            Dictionary<int, LinkedList<int>> EdgeMap = new Dictionary<int, LinkedList<int>>();

            Graph = new NetGraph(true);
            try
            {
                foreach (string line in lines) //create and add vertex to the graph
                {
                    string[] IDs = line.Split(' ');

                    if (int.TryParse(IDs[0], out nodeID))
                    {
                        foreach (string id in IDs)
                        {
                            int currID = int.Parse(id);
                            if (nodeList.Add(currID))
                            {
                               // _VList.Add(currID);
                                Graph.AddVertex(new NetVertex(currID));
                            }
                        }
                    }
                }
                for (int i = 0; i < nodeList.Count; i++)
                {
                    _VList.Add(nodeList.ElementAt(i));
                }
                this._IDCount = this._VList.Count();
                int from = 0, to = 0, curID = 0;
                int count = Graph.VertexCount;
                bool valid = true;
                //create edges, and keep record of vertex with edges going out for each valid vertex
                foreach (string line in lines)
                {
                    string[] IDs = line.Split(' ');

                    if (int.TryParse(IDs[0], out nodeID))
                    {
                        EdgeMap.Add(nodeID, new LinkedList<int>());
                        for (int j = 1; j < IDs.Length; j++)
                        {
                            curID = int.Parse(IDs[j]);
                            valid = true;
                            if(EdgeMap.ContainsKey(curID))
                            {
                                foreach (int id in EdgeMap[curID])
                                {
                                    if (id == nodeID) valid = false;
                                }
                            }
                            if (valid)
                            {
                                edgeOutNodes.Add(nodeID);
                                EdgeMap[nodeID].AddLast(curID);
                                for (int i = 0; i < count; i++)
                                {
                                    if (Graph.Vertices.ElementAt(i).ID == nodeID) from = i;
                                    if (Graph.Vertices.ElementAt(i).ID == curID) to = i;
                                }
                                this._AddNewGraphEdge(Graph.Vertices.ElementAt(from), Graph.Vertices.ElementAt(to));
                            }
                        }
                    }
                }

                //commodity is choosed at random, if that commodity does not already exist
                //check if it has valid path. if it exists then just add demand to it.

                for (int i = 0; i < _NumberOfCommoditiesVal; i++)
                {
                    CommoditySet = false;
                    while (!CommoditySet)
                    {
                        OriginID = random.Next(0, edgeOutNodes.Count);
                        OriginID = edgeOutNodes.ElementAt(OriginID);
                        DestID = random.Next(0, nodeList.Count);
                        DestID = nodeList.ElementAt(DestID);
                        demand = random.Next(MinComm, MaxComm);

                        for (int j = 0; j < Origins.Count; j++)
                        {
                            if (Origins[j] == OriginID && Destinations[j] == DestID)
                            {
                                CommoditySet = true;
                                Demands[j] += demand;
                                break;
                            }
                        }

                        if (CommoditySet) break;
                        this._path = null;
                        if (this._HasPath(OriginID, DestID, nodeList.Count, EdgeMap))
                        {
                           // this._GetSimulationEdges(OriginID, DestID);
                            Origins.Add(OriginID);
                            Destinations.Add(DestID);
                            Demands.Add(demand);
                            CommoditySet = true;
                        }
                    }
                }

                if (Origins.Count > 0) CommodityList.Remove(CommodityList.ElementAt(0));
                for (int i = 0; i < Origins.Count; i++)
                {
                    CommoditiesEntryViewModel cvm = new CommoditiesEntryViewModel();
                    cvm.OriginID = Origins[i];
                    cvm.DestinationID = Destinations[i];
                    cvm.DemandVal = Demands[i];
                    cvm.CombList = _VList;
                    cvm.ParentList = CommodityList;
                    CommodityList.Add(cvm);

                }

                NotifyPropertyChanged("Graph");
            }
            catch (Exception ex)
            {
                ExceptionMessage.Show("Something wrong with the Data in the File\n" + ex.ToString());
                Graph = null;
            }
        }
        private void _OpenDefaultGraph()
        {
            string[] lines = null;
            // Create an open file dialog box and only show *.grf files.
            try
            {
                OpenFileDialog openDlg = new OpenFileDialog();
                openDlg.Filter = "Graph File |*.grf";
                //read all lines of file
                if (true == openDlg.ShowDialog())
                {
                    lines = File.ReadAllLines(openDlg.FileName);

                    _openedFileName = openDlg.FileName;

                    Graph = new NetGraph(true);

                    //following block of code try to read the file and create graph
                    // to fully understant this code please read the graph file in notepad

                    string[] IDs = lines[0].Split(',');

                    foreach (string id in IDs)
                    {
                        int currID = int.Parse(id);
                        _VList.Add(currID);
                        Graph.AddVertex(new NetVertex(currID));

                    }
                    _IDCount = _VList.Count;

                    string[] edges = lines[1].Split(',');
                    string[] temp;
                    int idTo, idFrom;
                    int from = 0, to = 0;
                    int count = Graph.VertexCount;
                    foreach (string part in edges)
                    {
                        temp = part.Split('-');
                        idFrom = int.Parse(temp[0]);
                        idTo = int.Parse(temp[1]);

                        for (int i = 0; i < count; i++)
                        {
                            if (Graph.Vertices.ElementAt(i).ID == idFrom) from = i;
                            if (Graph.Vertices.ElementAt(i).ID == idTo) to = i;
                        }

                        //   _AddNewGraphEdge(_existingVertices[--idTo], _existingVertices[--idFrom]);
                        _AddNewGraphEdge(Graph.Vertices.ElementAt(from), Graph.Vertices.ElementAt(to));
                    }
                    string[] commodities = lines[2].Split(',');
                    if (commodities.Length > 0) CommodityList.RemoveAt(0);
                    foreach (string part in commodities)
                    {
                        temp = part.Split('-');
                        from = int.Parse(temp[0]);
                        to = int.Parse(temp[1]);
                        if (from != to)
                        {
                            CommoditiesEntryViewModel cvm = new CommoditiesEntryViewModel();
                            cvm.OriginID = from;
                            cvm.DestinationID = to;
                            cvm.DemandVal = int.Parse(temp[2]);
                            cvm.CombList = _VList;
                            cvm.ParentList = CommodityList;
                            CommodityList.Add(cvm);
                        }
                    }
                    NotifyPropertyChanged("Graph");
                }
            }
            catch (IOException e)
            {
                ExceptionMessage.Show("Could Not Open File\n" + e.ToString());
                Graph = null;
            }
            catch (Exception ex)
            {
                ExceptionMessage.Show("Something wrong with the Data in the File\n" + ex.ToString());
                Graph = null;
            }
        }