/// <summary>
        /// Create the NXF File
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        private static bool GetListOfTools(SetupInfo setup_info, PluginSettings plugin_settings, string output_dir, out PowerMILLExporter.Tools.Tools setup_tools)
        {
            List <PowerMILLExporter.Tools.NCProgramTool> oTools = new List <PowerMILLExporter.Tools.NCProgramTool>();
            int        iInitToolNum     = -1;
            bool       bReturn          = true;
            List <int> oUsedToolNumbers = new List <int>();

            PowerMILLAutomation.ExecuteEx(String.Format(System.Globalization.CultureInfo.InvariantCulture,
                                                        "$Powermill.Export.TriangleTolerance = \"{0}\"", plugin_settings.export_options.tool_tol));

            setup_tools = new PowerMILLExporter.Tools.Tools();
            // For each NC prog, create and add tools in list of tools
            for (int nc_i = 0; nc_i < setup_info.nc_progs.Count; nc_i++)
            {
                if (String.IsNullOrEmpty(setup_info.nc_progs[nc_i].sName))
                {
                    continue;
                }
                EventLogger.WriteToEvengLog("Get all toolpaths for nc program " + setup_info.nc_progs[nc_i].sName);

                setup_info.toolpaths = PowerMILLAutomation.GetNCProgToolpathes(setup_info.nc_progs[nc_i].sName);
                EventLogger.WriteToEvengLog("Get all tools for nc program " + setup_info.nc_progs[nc_i].sName);

                //OTools get's out of the function with the first toolpath missing
                MainModule.FillNCProgramTools(setup_info.nc_progs[nc_i].sName, setup_info.toolpaths, nc_i, out oTools, ref iInitToolNum);

                setup_info.nc_progs[nc_i].oTools = oTools;


                EventLogger.WriteToEvengLog("Get tool info for nc program " + setup_info.nc_progs[nc_i].sName);

                bReturn &= WriteTools.CreateListOfTools(setup_info.toolpaths, output_dir, setup_info.nc_progs, ref oUsedToolNumbers, ref setup_tools);
            }

            return(bReturn);
        }
        /// <summary>
        /// Fill the NCProg List
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        private static bool SetNCPrograms(ref XElement x_setup, SetupInfo setup_info, bool tool_id_use_num, bool tool_id_use_name)
        {
            bool bReturn = true;

            XElement target = x_setup.Descendants("NCPrograms").First();

            target.Attribute("Type").Value = "gcode";
            //Ask to remove toolpaths existing in the template
            if (target.Descendants("NCProgram") != null &&
                Messages.ShowWarning(Properties.Resources.IDS_RemoveNCCode) == System.Windows.MessageBoxResult.Yes)
            {
                target.Descendants("NCProgram").Remove();
            }

            if (target.Attribute("Change") == null)
            {
                target.Add(new XAttribute("Change", "tool_num"));
            }
            else
            {
                target.Attribute("Change").Value = "tool_num";
            }

            foreach (NCProgramInfo nc_prog in setup_info.nc_progs)
            {
                if (String.IsNullOrEmpty(nc_prog.sPath))
                {
                    continue;
                }
                target.Add(new XElement("NCProgram",
                                        new XAttribute("Use", "on"),
                                        new XAttribute("Filter", "off"),
                                        new XElement("File", nc_prog.sPath),
                                        new XElement("Orient", "None"),
                                        new XElement("Ident", "")));
            }

            target = x_setup.Descendants("ToolChange").First();
            if (target.Attribute("List") == null)
            {
                target.Add(new XAttribute("List", "tool_num"));
            }
            else
            {
                target.Attribute("List").Value = "tool_num";
            }
            target.RemoveAll();
            for (int nc_i = 0; nc_i < setup_info.nc_progs.Count; nc_i++)
            {
                if (setup_info.nc_progs[nc_i].oTools == null)
                {
                    continue;
                }
                foreach (PowerMILLExporter.Tools.NCProgramTool tool in setup_info.nc_progs[nc_i].oTools)
                {
                    target.Add(new XElement("Event",
                                            new XAttribute("NCProgram", nc_i + 1),
                                            new XAttribute("Filter", "on"),
                                            new XAttribute("Init", 1),
                                            new XElement("Cutter",
                                                         new XAttribute("Ident", WriteTools.ConstructToolName(tool.Number, tool.Name, tool_id_use_num, tool_id_use_name)),
                                                         "1:" + tool.Number),
                                            new XElement("Holder",
                                                         new XAttribute("Ident", WriteTools.ConstructToolName(tool.Number, tool.Name, tool_id_use_num, tool_id_use_name))),
                                            new XElement("Tool",
                                                         new XAttribute("Use", "other"),
                                                         new XAttribute("Teeth", 0),
                                                         new XAttribute("File", setup_info.nc_progs[nc_i].sPath),
                                                         new XAttribute("Line", 0))
                                            ));
                }

                if (x_setup.Descendants("Tool").Where(e => e.Attribute("CutterVisible") != null) == null)
                {
                    x_setup.Add(new XElement("Tool",
                                             new XAttribute("Change", "tool_num"),
                                             new XAttribute("CutterVisible", "all"),
                                             new XAttribute("HolderVisible", "all"),
                                             new XAttribute("Draw", "shaded"),
                                             new XAttribute("Control", "tip"),
                                             new XAttribute("HolderStockCollision", "on"),
                                             new XAttribute("HolderFixtureCollision", "on"),
                                             new XAttribute("CutterFixtureCollision", "on"),
                                             new XAttribute("HolderStockNearMiss", 0),
                                             new XAttribute("HolderFixtureNearMiss", 0),
                                             new XAttribute("CutterFixtureNearMiss", 0),
                                             new XAttribute("Gouge", "off"),
                                             new XAttribute("HolderStockCollision", "on")));
                }
                else
                {
                    IEnumerable <XElement> cutters = x_setup.Descendants("Tool").Where(e => e.Attribute("CutterVisible") != null);
                    if (cutters.Count() != 0)
                    {
                        target = cutters.First();
                        if (tool_id_use_name)
                        {
                            if (target.Attribute("Change") == null)
                            {
                                target.Add(new XAttribute("Change", "tool_num"));
                            }
                            else
                            {
                                target.Attribute("Change").Value = "tool_num";
                            }
                        }
                    }
                }

                //<Event NCProgram="1" Filter="on" Init="1"> //LINE DONE
                //  <Cutter Ident="Main_Upper_01">1:1</Cutter>
                //  <Holder Ident="Main_Upper_01"/>
                //  <Tool Use="other" Teeth="0" File="C:\VERICUT\33B3262_R_V2_NTJX\33B3262_R_V2_NTJX.mcd" Line="0"></Tool>
                //</Event>
            }
            return(bReturn);
        }
        /// <summary>
        /// Create the different Output Files
        /// </summary>
        /// <remarks>nxf File,stl, iso, ...</remarks>
        public static string CreateOutputFiles(ProjectData proj_data, string output_dir, PluginSettings plugin_settings)
        {
            string project_fpath = Path.Combine(output_dir, ProjectData.ProjectName + ".vcproject");

            XDocument main_doc;

            try
            {
                main_doc = XDocument.Load(proj_data.proj_template);
            }
            catch
            {
                Messages.ShowError(Properties.Resources.IDS_VericutTemplateReadFailure, proj_data.proj_template);
                return("*");
            }

            main_doc.Descendants("Setup").Remove();
            if (main_doc.Descendants("InfoUserName").Count() > 0)
            {
                main_doc.Descendants("InfoUserName").First().Value =
                    String.Format("PowerMill to Vericut plugin v{0}.{1}.{2}",
                                  System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Major,
                                  System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Minor,
                                  System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Build);
            }

            for (int i = 0; i < proj_data.setup_infos.Count; i++)
            {
                XDocument doc;
                XElement  setup;
                SetupInfo setup_info = proj_data.setup_infos[i];

                PowerMILLAutomation.CreateTransformWorkplane("Transform_Vericut");
                PowerMILLAutomation.ActivateWorkplane(setup_info.attach_workplane);
                //WorkPlaneOrigin model_origin = MainModule.GetWorkplaneCoords(PowerMILLAutomation.oToken, setup_info.model_workplane, false, Properties.Resources.IDS_WorkplaneFailedToGet);
                WorkPlaneOrigin model_origin = MainModule.GetWorkplaneCoords(PowerMILLAutomation.oToken, "Transform_Vericut", true, Properties.Resources.IDS_WorkplaneFailedToGet);//Changed relation to true and look for the Transform position from the model location to align correctly in Vericut
                PowerMILLAutomation.DeleteTransformWorkplane("Transform_Vericut");


                string template = null;
                if (String.IsNullOrEmpty(setup_info.template) || !File.Exists(setup_info.template))
                {
                    template = proj_data.proj_template;
                }
                else
                {
                    template = setup_info.template;
                }
                doc = XDocument.Load(template);

                // Add path to items from the template
                IEnumerable <XElement> rows = doc.Descendants("File");
                foreach (XElement file in rows.ToList())
                {
                    string file_name = (file.FirstNode != null) ? file.FirstNode.ToString() : null;
                    if (!String.IsNullOrEmpty(file_name) && !String.IsNullOrEmpty(Path.GetExtension(file_name)) &&
                        String.IsNullOrEmpty(Path.GetDirectoryName(file_name)))
                    {
                        string full_path   = Path.Combine(Path.GetDirectoryName(template), file_name);
                        string new_element = file.ToString().Replace(file_name, full_path);

                        file.ReplaceWith(XElement.Parse(new_element));
                    }
                }

                setup = doc.Descendants("Setup").First();
                setup.Attribute("Name").Value = setup_info.name;

                PowerMILLExporter.Tools.Tools setup_tools;
                GetListOfTools(setup_info, plugin_settings, proj_data.output_dir, out setup_tools);
                setup_info.oTools = setup_tools;

                if (setup_info.tools_to_use == 0)
                {
                    EventLogger.WriteToEvengLog("Write tool info to tools.xml");
                    WriteTools.WriteToolsToXML(setup_info.oTools, output_dir, setup_info.name + "_tools.tls", plugin_settings.tool_id_use_num, plugin_settings.tool_id_use_name);

                    //output_dir, setup_info.name + "_tools.tls"
                    SetTools(ref setup, Path.Combine(output_dir, setup_info.name + "_tools.tls"));
                }
                else
                {
                    List <string> lib_tools     = GetListOfToolsFromLibrary(setup_info.tls_fpath);
                    List <string> missing_tools = WriteTools.FindToolsMissingFromLibrary(setup_info.oTools, lib_tools);
                    if (missing_tools.Count > 0)
                    {
                        if (setup_info.tools_to_use == 1)
                        {
                            Messages.ShowWarning(String.Format("Setup {0}: the following tools are missing from the library:\r\n {1}.", setup_info.name, String.Join(Environment.NewLine, missing_tools.ToArray())));
                        }
                        else if (setup_info.tools_to_use == 2)
                        {
                            EventLogger.WriteToEvengLog("Write tool info to tools.xml");
                            WriteTools.AppendToolsToXML(setup_info.oTools, output_dir, setup_info.tls_fpath, missing_tools);

                            //output_dir, setup_info.name + "_tools.tls"
                            SetTools(ref setup, Path.Combine(output_dir, setup_info.tls_fpath));
                        }
                    }
                }

                SetWorkOffsets(ref setup, setup_info);

                if (setup_info.tools_to_use == 1 || setup_info.tools_to_use == 2)
                {
                    SetNCPrograms(ref setup, setup_info, false, true);
                }
                else
                {
                    SetNCPrograms(ref setup, setup_info, plugin_settings.tool_id_use_num, plugin_settings.tool_id_use_name);
                }

                SetCSysInfo(ref setup, setup_info, proj_data.cut_stock_csys);

                /* Don't set block info for 2nd and other setups if using cut stock transition */
                if (i == 0 || String.IsNullOrEmpty(proj_data.cut_stock_csys))
                {
                    SetBlockInfo(ref setup, output_dir, setup_info, model_origin, plugin_settings.export_options.block_tol);
                }

                SetFixturesInfo(ref setup, output_dir, setup_info, model_origin, plugin_settings.export_options.fixture_tol);

                /* Don't set part info for 2nd and other setups if using cut stock transition */
                if (i == 0 || String.IsNullOrEmpty(proj_data.cut_stock_csys))
                {
                    SetPartsInfo(ref setup, output_dir, setup_info, model_origin, plugin_settings.export_options.model_tol);
                }

                if (i == 0)
                {
                    main_doc.Elements("VcProject").First().Add(setup);
                }
                else
                {
                    if (main_doc.Descendants("Setup").Count() > 0)
                    {
                        main_doc.Descendants("Setup").Last().AddAfterSelf(setup);
                    }
                }
            }

            main_doc.Save(project_fpath);


            return(project_fpath);
        }