//add "Element ID" fields to segment and fitting fields
        public void upgrade1(PressureLossReportData data, int nVersion = 1)
        {
            if (data == null || data.Version >= nVersion)
            return;

             //segment
             {
            PressureLossParameter PLParam = new PressureLossParameter(ReportResource.elementId, false, -1, (int)SectionMemberType.Segment);
            if (!data.StraightSegFields.Contains(PLParam))
               data.StraightSegFields.Add(PLParam);
             }

             //fitting
             {
            PressureLossParameter PLParam = new PressureLossParameter(ReportResource.elementId, false, -1, (int)SectionMemberType.Fitting);
            if (!data.FittingFields.Contains(PLParam))
               data.FittingFields.Add(PLParam);
             }

             data.Version = nVersion;
             PressureLossReportDataManager.Instance.save(data);
        }
        public static void generateSegmentFields(PressureLossReportData reportData)
        {
            PressureLossReportHelper helper = PressureLossReportHelper.instance;
             if (helper == null)
            return;

             List<PressureLossParameter> segParameters = new List<PressureLossParameter>();

             //default segment selected fields
             //SectionMemberType means where the value is from: segment or section
             int nOrder = 1;
             segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.ALL_MODEL_MARK), false, -1, (int)SectionMemberType.Segment));
             segParameters.Add(new PressureLossParameter(ReportResource.elementId, true, nOrder++, (int)SectionMemberType.Segment));

             if (helper.Domain == ReportResource.pipeDomain)
             {
            segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_FLOW_PARAM), true, nOrder++, (int)SectionMemberType.Section));
            segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_SIZE_FORMATTED_PARAM), true, nOrder++, (int)SectionMemberType.Segment));
            segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_FRICTION_FACTOR_PARAM), false, -1, (int)SectionMemberType.Section));
            segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_FIXTURE_UNITS_PARAM), false, -1, (int)SectionMemberType.Section));
            segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_REYNOLDS_NUMBER_PARAM), false, -1, (int)SectionMemberType.Section));
            segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_FITTING_LOSS_KFACTOR_PARAM), false, -1, (int)SectionMemberType.Section));
             }
             else
             {
            segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_DUCT_FLOW_PARAM), true, nOrder++, (int)SectionMemberType.Section));
            segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_DUCT_SIZE_FORMATTED_PARAM), true, nOrder++, (int)SectionMemberType.Segment));
            segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_REYNOLDSNUMBER_PARAM), false, -1, (int)SectionMemberType.Section));
            segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_LOSS_COEFFICIENT), false, -1, (int)SectionMemberType.Section));
             }

             segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_VELOCITY), true, nOrder++, (int)SectionMemberType.Section));
             segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_VELOCITY_PRESSURE), true, nOrder++, (int)SectionMemberType.Section));
             segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.CURVE_ELEM_LENGTH), true, nOrder++, (int)SectionMemberType.Section));
             segParameters.Add(new PressureLossParameter(ReportResource.pressureLoss, true, 100, (int)SectionMemberType.Section, false));

             segParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_FRICTION), false, -1, (int)SectionMemberType.Section));

             //find the first curve
             List<MEPSystem> systems = helper.getSortedSystems();
             if (systems == null || systems.Count < 1)
            return;
             foreach (MEPSystem system in systems)
             {
            List<MEPSection> sections = new List<MEPSection>();
            MEPSystemInfo.getSectionsFromSystem(system, sections);
            foreach (MEPSection section in sections)
            {
               //find one section which contains both segment and fitting
               List<MEPCurve> curves = new List<MEPCurve>();
               SectionsInfo.getSectionElements(section, curves, null, null, null);

               if (curves.Count < 1)
                  continue;

               //segment parameters
               PressureLossParameter PLParam1 = new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.ELEM_FAMILY_PARAM), false, -1, (int)SectionMemberType.Type);
               if (!segParameters.Contains(PLParam1))
                  segParameters.Add(PLParam1);

               PressureLossParameter PLParam2 = new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM), false, -1, (int)SectionMemberType.Type);
               if (!segParameters.Contains(PLParam2))
                  segParameters.Add(PLParam2);

               PressureLossParameter PLParam3 = new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_SIZE_FORMATTED_PARAM), false, -1, (int)SectionMemberType.Segment);
               if (!segParameters.Contains(PLParam3))
                  segParameters.Add(PLParam3);

               foreach (Parameter param in curves[0].Parameters)
               {
                  //exclude the parameters under constrain and other groups
                  if (param.Definition.ParameterGroup == BuiltInParameterGroup.PG_CONSTRAINTS
                     || LabelUtils.GetLabelFor(param.Definition.ParameterGroup) == ReportResource.other
                     || param.Definition.Name == LabelUtils.GetLabelFor(BuiltInParameter.RBS_SECTION)
                     || param.Definition.Name == LabelUtils.GetLabelFor(BuiltInParameter.RBS_PRESSURE_DROP))
                     continue;

                  PressureLossParameter PLParam = new PressureLossParameter(param.Definition.Name, false, -1, (int)SectionMemberType.Segment);
                  if (!segParameters.Contains(PLParam))
                     segParameters.Add(PLParam);
               }

               //segmentType parameters
               MEPCurveType crvType = helper.Doc.GetElement(curves[0].GetTypeId()) as MEPCurveType;
               if (crvType != null)
               {
                  foreach (Parameter param in crvType.Parameters)
                  {
                     //exclude the parameters under Fitting/Segments and other groups
                     if (param.Definition.ParameterGroup == BuiltInParameterGroup.PG_FITTING
                     || param.Definition.ParameterGroup == BuiltInParameterGroup.PG_SEGMENTS_FITTINGS
                     || LabelUtils.GetLabelFor(param.Definition.ParameterGroup) == ReportResource.other)
                        continue;

                     PressureLossParameter PLParam = new PressureLossParameter(param.Definition.Name, false, -1, (int)SectionMemberType.Type);
                     if (!segParameters.Contains(PLParam))
                        segParameters.Add(PLParam);
                  }
               }

               reportData.StraightSegFields = segParameters;

               return;
            }
             }
        }
        public static void generateFittingFields(PressureLossReportData reportData)
        {
            if (reportData == null)
            return;

             PressureLossReportHelper helper = PressureLossReportHelper.instance;
             if (helper == null)
            return;

             List<PressureLossParameter> fittingParameters = new List<PressureLossParameter>();

             //default fitting selected fields
             //SectionMemberType means where the value is from: section or fitting
             int nOrder = 1;
             fittingParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.ALL_MODEL_MARK), false, -1, (int)SectionMemberType.Fitting));
             fittingParameters.Add(new PressureLossParameter(ReportResource.elementId, true, nOrder++, (int)SectionMemberType.Fitting));

             if (helper.Domain == ReportResource.pipeDomain)
            fittingParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_FITTING_LOSS_METHOD_SERVER_PARAM), true, nOrder++, (int)SectionMemberType.Fitting));
             else
            fittingParameters.Add(new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_DUCT_FITTING_LOSS_METHOD_SERVER_PARAM), true, nOrder++, (int)SectionMemberType.Fitting));

             //pressure loss fields is not visible in settings dialog, the order 100 is to make sure it always is the last one field
             fittingParameters.Add(new PressureLossParameter(ReportResource.pressureLoss, true, 100, (int)SectionMemberType.Section, false));

             //find the first fitting
             List<MEPSystem> systems = helper.getSortedSystems();
             if (systems == null || systems.Count < 1)
            return;
             foreach (MEPSystem system in systems)
             {
            List<MEPSection> sections = new List<MEPSection>();
            MEPSystemInfo.getSectionsFromSystem(system, sections);
            foreach (MEPSection section in sections)
            {
               //find one section which contains both segment and fitting
               List<FamilyInstance> fittings = new List<FamilyInstance>();

               SectionsInfo.getSectionElements(section, null, fittings, null, null);

               if (fittings.Count < 1)
                  continue;

               //fitting's instance parameters

               PressureLossParameter PLParam1 = new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.ELEM_FAMILY_PARAM), false, -1, (int)SectionMemberType.Type);
               if (!fittingParameters.Contains(PLParam1))
                  fittingParameters.Add(PLParam1);

               PressureLossParameter PLParam2 = new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM), false, -1, (int)SectionMemberType.Type);
               if (!fittingParameters.Contains(PLParam2))
                  fittingParameters.Add(PLParam2);

               PressureLossParameter PLParam3 = new PressureLossParameter(LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_SIZE_FORMATTED_PARAM), false, -1, (int)SectionMemberType.Fitting);
               if (!fittingParameters.Contains(PLParam3))
                  fittingParameters.Add(PLParam3);

               foreach (Parameter param in fittings[0].Parameters)
               {
                  //exclude the parameters under constrains/Graphics/Geometry and other groups
                  if (param.Definition.ParameterGroup == BuiltInParameterGroup.PG_CONSTRAINTS
                     || param.Definition.ParameterGroup == BuiltInParameterGroup.PG_GRAPHICS
                     || param.Definition.ParameterGroup == BuiltInParameterGroup.PG_GEOMETRY
                     || LabelUtils.GetLabelFor(param.Definition.ParameterGroup) == ReportResource.other
                     || param.Definition.Name == LabelUtils.GetLabelFor(BuiltInParameter.RBS_DUCT_PRESSURE_DROP))
                     continue;

                  PressureLossParameter PLParam = new PressureLossParameter(param.Definition.Name, false, -1, (int)SectionMemberType.Fitting);
                  if (!fittingParameters.Contains(PLParam))
                     fittingParameters.Add(PLParam);
               }

               //Fitting symbol parameters

               FamilySymbol famSym = fittings[0].Symbol;
               if (famSym != null)
               {

                  foreach (Parameter param in famSym.Parameters)
                  {
                     //exclude the parameters under construction and other groups
                     if ( param.Definition.ParameterGroup == BuiltInParameterGroup.PG_CONSTRUCTION
                        || LabelUtils.GetLabelFor(param.Definition.ParameterGroup) == ReportResource.other)
                        continue;

                     PressureLossParameter PLParam = new PressureLossParameter(param.Definition.Name, false, -1, (int)SectionMemberType.Type);
                     if (!fittingParameters.Contains(PLParam))
                        fittingParameters.Add(PLParam);
                  }
               }

               reportData.FittingFields = fittingParameters;

               return;
            }
             }
        }
        /************************************************************************/
        /* For pipe fitting and accessory, remove coefficient
           *
           *
           */
        /************************************************************************/
        public void upgrade4(PressureLossReportData data, int nVersion = 4)
        {
            if (data == null || data.Version >= nVersion)
            return;

             PressureLossReportHelper helper = PressureLossReportHelper.instance;
             if (helper == null)
            return;

             string fieldLossMethodName = LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_FITTING_LOSS_METHOD_PARAM);
             string fieldKFactorName = LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_FITTING_LOSS_KFACTOR_PARAM);
             string fieldKTableName = LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_FITTING_LOSS_TABLE_PARAM);

             string fieldNewLossMethodName = LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_FITTING_LOSS_METHOD_SERVER_PARAM);

             int nDisplayOrder = -1;
             if (data.Domain == ReportResource.pipeDomain) //Remove the 3 old parameters for pipe
             {
            PressureLossParameter PLParam1 = helper.getPressureLossParamByName(data.FittingFields, fieldLossMethodName);
            if (PLParam1 != null)
            {
               nDisplayOrder = PLParam1.DisplayOrder;
               data.FittingFields.Remove(PLParam1);
            }

            PressureLossParameter PLParam2 = helper.getPressureLossParamByName(data.FittingFields, fieldKFactorName);
            if (PLParam2 != null)
               data.FittingFields.Remove(PLParam2);

            PressureLossParameter PLParam3 = helper.getPressureLossParamByName(data.FittingFields, fieldKTableName);
            if (PLParam3 != null)
               data.FittingFields.Remove(PLParam3);

            //Add the new loss method as selected field for pipe
            PressureLossParameter PLParam = new PressureLossParameter(fieldNewLossMethodName, true, nDisplayOrder, (int)SectionMemberType.Fitting);
            if (!data.FittingFields.Contains(PLParam))
               data.FittingFields.Add(PLParam);
             }

             data.Version = nVersion;
             PressureLossReportDataManager.Instance.save(data);
        }