public static List <SerVolTablesByClass> WriteFDOTServiceVolInputFile()
        {
            List <SerVolTablesByClass> SerVolTables = new List <SerVolTablesByClass>();
            string Filename = "FDOTServiceVolsInputData.xml";

            foreach (AreaType areaType in Enum.GetValues(typeof(AreaType)))
            {
                if (areaType == AreaType.Transitioning || areaType == AreaType.LargeUrbanized || areaType == AreaType.RuralDeveloped)
                {
                    SerVolTablesByClass TablesForClass = new SerVolTablesByClass();
                    foreach (ArterialClass artClass in Enum.GetValues(typeof(ArterialClass)))
                    {
                        if (!(areaType == AreaType.RuralDeveloped && artClass == ArterialClass.ClassII)) // Ignore Class II Rural since it doesn't exist
                        {
                            TablesForClass.SerVolTablesMultiLane.Add(CreateArterial_FDOTSerVols.CreateServiceVolTableFDOT(areaType, artClass));
                        }
                    }
                    TablesForClass.ArtAreaType = areaType;
                    SerVolTables.Add(TablesForClass);
                }
            }
            FileIOserviceVols.SerializeServiceVolInputData(Filename, SerVolTables);
            return(SerVolTables);
        }
        /// <summary>
        /// Creates the Service Volumes for an arterial based on input parameters.
        /// </summary>
        /// <param name="Project"></param>
        /// <param name="SerVol"></param>
        /// <param name="inputsOneLane"></param>
        /// <param name="inputsMultiLane"></param>

        /*public static void ServiceVolsAuto(ProjectData Project, ServiceVolumes SerVol, ServiceVolumeArterialInputs
         * inputsOneLane, ServiceVolumeArterialInputs inputsMultiLane)
         * {
         *
         *  float NumberOfLoops = 5 * 5;  //This accounts for LOS and Lanes, does not account for volume increments; Type is float just to avoid extra cast in calculations below
         *  int LoopCounter = 0;
         *  frmMain.bgwRunServiceVolsCalcs.ReportProgress(0);
         *
         *  ArterialData Arterial = new ArterialData();
         *  for (int lanes = 0; lanes < 5; lanes++) // 2,4,6,8,*
         *  {
         *      int vol = 40; // Starting volume (volume entering upstream of first intersection)
         *      bool threshExceeded = false;
         *
         *      // Variable access points
         *
         *      ServiceVolumeArterialInputs inputsForArterialCreation = inputsOneLane;
         *      if (lanes > 0)
         *          inputsForArterialCreation = inputsMultiLane;
         *
         *      if (lanes != 4)
         *          Arterial = CreateArterial_FDOTSerVols.NewArterial(inputsForArterialCreation, vol, lanes + 1);
         *      else
         *          Arterial = CreateArterial_FDOTSerVols.NewArterial(inputsForArterialCreation, vol);
         *
         *      for (int LOSlevel = 0; LOSlevel < 5; LOSlevel++) // LOS A-E
         *      {
         *          LoopCounter++;
         *
         *          int[] ServiceVolsArray;
         *          do
         *          {
         *              CreateArterial_FDOTSerVols.ChangeArterialVolume(ref Arterial, vol);
         *              Arterial.TestSerVol = vol;
         *              CalcsArterial.CalcResults(Project, ref Arterial);
         *
         *              if (!Arterial.OverCapacity)
         *              {
         *                  // Check whether LOS speed threshold has been exceeded
         *                  if (Arterial.Results.AverageSpeed < Arterial.Thresholds.Speed[LOSlevel])  // Avg. speed below LOS threshold speed
         *                  {
         *                      vol -= 10;
         *                      threshExceeded = true;
         *                      if (vol <= 0)
         *                      {
         *                          vol = 10;
         *                          SerVol.PkDirVol[lanes, LOSlevel] = -1;
         *                          SerVol.BothDirVol[lanes, LOSlevel] = -1;
         *                          SerVol.AADT[lanes, LOSlevel] = -1;
         *                          SerVol.Found[lanes, LOSlevel] = true;
         *                      }
         *                  }
         *                  else
         *                  {
         *                      if (threshExceeded == false) // Threshold not exceeded, increment volume
         *                      {
         *                          if ((Arterial.Results.AverageSpeed - Arterial.Thresholds.Speed[LOSlevel]) > 5)
         *                              vol += (30 * (lanes + 1) * (LOSlevel + 1));
         *                          else
         *                              vol += 10;
         *                      }
         *                      else // Threshold exceeded, record volume for LOS level
         *                      {
         *                          if (LOSlevel > 0)
         *                              ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, SerVol.PkDirVol[lanes, LOSlevel - 1]);
         *                          else
         *                              ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, -1);
         *                          SerVol.PkDirVol[lanes, LOSlevel] = ServiceVolsArray[0];
         *                          SerVol.BothDirVol[lanes, LOSlevel] = ServiceVolsArray[1];
         *                          SerVol.AADT[lanes, LOSlevel] = ServiceVolsArray[2];
         *                          SerVol.Found[lanes, LOSlevel] = true;
         *                          vol += 10; // Increment volume for start of next LOS level
         *                          threshExceeded = false;
         *                      }
         *                  }
         *              }
         *              else  // Check to see if there is a constraining intersection due to (v/c * PHF) > 1
         *              {
         *                  vol -= 10; // Return to the previous non-capacity-constrained volume
         *                  for (int capCheckLOSlevel = LOSlevel + 1; capCheckLOSlevel < 5; capCheckLOSlevel++) // LOS A-E
         *                  {
         *                      SerVol.PkDirVol[lanes, capCheckLOSlevel] = -2;
         *                      SerVol.BothDirVol[lanes, capCheckLOSlevel] = -2;
         *                      SerVol.AADT[lanes, capCheckLOSlevel] = -2;
         *                      SerVol.Found[lanes, capCheckLOSlevel] = true;
         *                  }
         *                  if (LOSlevel > 0)
         *                      ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, SerVol.PkDirVol[lanes, LOSlevel - 1]);
         *                  else
         *                      ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, -1);
         *                  SerVol.PkDirVol[lanes, LOSlevel] = ServiceVolsArray[0];
         *                  SerVol.BothDirVol[lanes, LOSlevel] = ServiceVolsArray[1];
         *                  SerVol.AADT[lanes, LOSlevel] = ServiceVolsArray[2];
         *                  SerVol.Found[lanes, LOSlevel] = true;
         *              }
         *          }
         *          while (SerVol.Found[lanes, LOSlevel] == false);     //loop until service vol reached for given LOS
         *          if (Arterial.OverCapacity)
         *          {
         *              LoopCounter = 5 * (lanes + 1);
         *              frmMain.bgwRunServiceVolsCalcs.ReportProgress((int)(Math.Round(LoopCounter / NumberOfLoops * 100, 0, MidpointRounding.AwayFromZero)));
         *              break;
         *          }
         *          frmMain.bgwRunServiceVolsCalcs.ReportProgress((int)(Math.Round(LoopCounter / NumberOfLoops * 100, 0, MidpointRounding.AwayFromZero)));
         *      } // BP here to view service volumes by LOS
         *  } // BP here to view service volumes by number of lanes
         * } // BP here to view all service volumes*/

        public static void ServiceVolsAutoNew(ProjectData Project, ServiceVolumes SerVol, ServiceVolumeTableFDOT inputsOneLane, ServiceVolumeTableFDOT inputsMultiLane)
        {
            float NumberOfLoops = 5 * 5;  //This accounts for LOS and Lanes, does not account for volume increments; Type is float just to avoid extra cast in calculations below
            int   LoopCounter   = 0;

            frmMain.bgwRunServiceVolsCalcs.ReportProgress(0);

            ArterialData Arterial = new ArterialData();

            for (int lanes = 0; lanes < 5; lanes++) // 2,4,6,8,*
            {
                int  vol            = 40;           // Starting volume (volume entering upstream of first intersection)
                bool threshExceeded = false;

                // Variable access points

                ServiceVolumeTableFDOT inputsForArterialCreation = inputsOneLane;
                if (lanes > 0)
                {
                    inputsForArterialCreation = inputsMultiLane;
                }

                if (lanes != 4)
                {
                    Arterial = CreateArterial_FDOTSerVols.NewArterial(inputsForArterialCreation, Project.AnalMode, vol, lanes + 1);
                }
                else
                {
                    Arterial = CreateArterial_FDOTSerVols.NewArterial(inputsForArterialCreation, Project.AnalMode, vol);
                }

                for (int LOSlevel = 0; LOSlevel < 5; LOSlevel++) // LOS A-E
                {
                    LoopCounter++;

                    int[] ServiceVolsArray;
                    do
                    {
                        CreateArterial_FDOTSerVols.ChangeArterialVolume(ref Arterial, vol);
                        Arterial.TestSerVol = vol;
                        CalcsArterial.CalcResults(Project, ref Arterial);

                        if (!Arterial.OverCapacity)
                        {
                            // Check whether LOS speed threshold has been exceeded
                            if (Arterial.Results.AverageSpeed < Arterial.Thresholds.Speed[LOSlevel])  // Avg. speed below LOS threshold speed
                            {
                                vol           -= 10;
                                threshExceeded = true;
                                if (vol <= 0)
                                {
                                    vol = 10;
                                    SerVol.PkDirVol[lanes, LOSlevel]   = -1;
                                    SerVol.BothDirVol[lanes, LOSlevel] = -1;
                                    SerVol.AADT[lanes, LOSlevel]       = -1;
                                    SerVol.Found[lanes, LOSlevel]      = true;
                                }
                            }
                            else
                            {
                                if (threshExceeded == false) // Threshold not exceeded, increment volume
                                {
                                    if ((Arterial.Results.AverageSpeed - Arterial.Thresholds.Speed[LOSlevel]) > 5)
                                    {
                                        vol += (30 * (lanes + 1) * (LOSlevel + 1));
                                    }
                                    else
                                    {
                                        vol += 10;
                                    }
                                }
                                else // Threshold exceeded, record volume for LOS level
                                {
                                    //vol += 10;
                                    if (LOSlevel > 0)
                                    {
                                        ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, SerVol.PkDirVol[lanes, LOSlevel - 1]);
                                    }
                                    else
                                    {
                                        ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, -1);
                                    }
                                    SerVol.PkDirVol[lanes, LOSlevel]   = ServiceVolsArray[0];
                                    SerVol.BothDirVol[lanes, LOSlevel] = ServiceVolsArray[1];
                                    SerVol.AADT[lanes, LOSlevel]       = ServiceVolsArray[2];
                                    SerVol.Found[lanes, LOSlevel]      = true;
                                    vol           += 10; // Increment volume for start of next LOS level
                                    threshExceeded = false;
                                }
                            }
                        }
                        else  // Check to see if there is a constraining intersection due to (v/c * PHF) > 1
                        {
                            vol -= 10; // Return to the previous non-capacity-constrained volume
                            for (int capCheckLOSlevel = LOSlevel + 1; capCheckLOSlevel < 5; capCheckLOSlevel++) // LOS A-E
                            {
                                SerVol.PkDirVol[lanes, capCheckLOSlevel]   = -2;
                                SerVol.BothDirVol[lanes, capCheckLOSlevel] = -2;
                                SerVol.AADT[lanes, capCheckLOSlevel]       = -2;
                                SerVol.Found[lanes, capCheckLOSlevel]      = true;
                            }
                            if (LOSlevel > 0)
                            {
                                ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, SerVol.PkDirVol[lanes, LOSlevel - 1]);
                            }
                            else
                            {
                                ServiceVolsArray = SetServiceVolumes(vol, Project.Period, Arterial.Dfactor, Arterial.Kfactor, LOSlevel, -1);
                            }
                            SerVol.PkDirVol[lanes, LOSlevel]   = ServiceVolsArray[0];
                            SerVol.BothDirVol[lanes, LOSlevel] = ServiceVolsArray[1];
                            SerVol.AADT[lanes, LOSlevel]       = ServiceVolsArray[2];
                            SerVol.Found[lanes, LOSlevel]      = true;
                        }
                    }while (SerVol.Found[lanes, LOSlevel] == false);     //loop until service vol reached for given LOS
                    threshExceeded = false;
                    if (Arterial.OverCapacity)
                    {
                        LoopCounter = 5 * (lanes + 1);
                        frmMain.bgwRunServiceVolsCalcs.ReportProgress((int)(Math.Round(LoopCounter / NumberOfLoops * 100, 0, MidpointRounding.AwayFromZero)));
                        break;
                    }
                    frmMain.bgwRunServiceVolsCalcs.ReportProgress((int)(Math.Round(LoopCounter / NumberOfLoops * 100, 0, MidpointRounding.AwayFromZero)));
                } // BP here to view service volumes by LOS
            }     // BP here to view service volumes by number of lanes
        }         // BP here to view all service volumes