/************************************************************************/

        /* 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);
        }
        private bool getFittingInfo(MEPSection section, DataTable fittingTB, bool forHTML = false)
        {
            if (fittingTB == null || section == null)
            {
                return(false);
            }

            PressureLossReportHelper helper = PressureLossReportHelper.instance;

            if (helper == null || helper.ReportData == null)
            {
                return(false);
            }

            List <string> fittingFields = new List <string>();

            if (helper.ReportData.FittingFields != null)
            {
                getFields(fittingFields);
            }

            if (forHTML)
            {
                helper.addColumns(fittingTB, fittingFields.Count);
            }
            else
            {
                helper.addColumns(fittingTB, fittingFields.Count + 2);
            }

            List <FamilyInstance> fittings = new List <FamilyInstance>();

            SectionsInfo.getSectionElements(section, null, fittings, null, null);
            if (fittings.Count < 1)
            {
                return(false);
            }

            int nIndex = 0;

            foreach (FamilyInstance fitting in fittings)
            {
                List <string> paramVals = new List <string>();
                if (!forHTML)
                {
                    if (nIndex == 0)
                    {
                        paramVals.Add(section.Number.ToString());
                    }
                    else
                    {
                        paramVals.Add(" ");
                    }
                }

                foreach (string fieldName in fittingFields)
                {
                    try
                    {
                        PressureLossParameter PLParam = helper.getPressureLossParamByName(helper.ReportData.FittingFields, fieldName);
                        if (PLParam == null)
                        {
                            continue;
                        }

                        string strVal = ReportConstants.emptyValue;
                        if ((PLParam.GetFrom & (int)SectionMemberType.Section) > 0)
                        {
                            strVal = SectionsInfo.getSectionInfoByParamName(section, fieldName, PLParam.GetFrom, fitting.Id);
                        }
                        else if ((PLParam.GetFrom & (int)SectionMemberType.Fitting) > 0)
                        {
                            if (helper.Domain == ReportResource.pipeDomain && fieldName == LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_FITTING_LOSS_METHOD_SERVER_PARAM))
                            {
                                string strValGUID = fitting.get_Parameter(fieldName).AsString();
                                Guid   serverGUID = new Guid(strValGUID);

                                //convert the GUID to server name
                                //get the service first, and then get the server
                                MultiServerService service = ExternalServiceRegistry.GetService(ExternalServices.BuiltInExternalServices.PipeFittingAndAccessoryPressureDropService) as MultiServerService;
                                if (service != null && serverGUID != null)
                                {
                                    IExternalServer server = service.GetServer(new Guid(strValGUID));
                                    if (server != null)
                                    {
                                        strVal = server.GetName();
                                    }
                                }
                            }
                            else if (helper.Domain == ReportResource.ductDomain && fieldName == LabelUtils.GetLabelFor(BuiltInParameter.RBS_DUCT_FITTING_LOSS_METHOD_SERVER_PARAM))
                            {
                                string strValGUID = fitting.get_Parameter(fieldName).AsString();
                                Guid   serverGUID = new Guid(strValGUID);

                                //convert the GUID to server name
                                //get the service first, and then get the server
                                MultiServerService service = ExternalServiceRegistry.GetService(ExternalServices.BuiltInExternalServices.DuctFittingAndAccessoryPressureDropService) as MultiServerService;
                                if (service != null && serverGUID != null)
                                {
                                    IExternalServer server = service.GetServer(new Guid(strValGUID));
                                    if (server != null)
                                    {
                                        strVal = server.GetName();
                                    }
                                }
                            }
                            else if (fieldName == ReportResource.elementId)
                            {
                                strVal = fitting.Id.ToString();
                            }
                            else
                            {
                                strVal = helper.getParamValue(fitting.get_Parameter(fieldName));
                            }
                        }
                        else if ((PLParam.GetFrom & (int)SectionMemberType.Type) > 0)
                        {
                            strVal = getFittingSymbolInfoByParamName(fitting, fieldName);
                        }

                        paramVals.Add(strVal);
                    }
                    catch
                    {
                        //...
                    }
                }

                if (!forHTML) //for csv, the last column is section pressure loss report
                {
                    string strVal = ReportConstants.mergeValue;
                    if (nIndex == 0)
                    {
                        strVal = helper.getTotalPressureLossByType(section, SectionMemberType.Fitting);
                    }

                    paramVals.Add(strVal);
                }

                nIndex++;

                helper.addRow(fittingTB, paramVals);
            }

            return(true);
        }
        private void getSectionTable(MEPSection section, DataTable tb, List <string> fileds, PressureLossReportData reportData, bool bForHtml = false)
        {
            if (tb == null || fileds == null || section == null || reportData == null)
            {
                return;
            }

            List <MEPCurve>       curves       = new List <MEPCurve>();
            List <FamilyInstance> fittings     = new List <FamilyInstance>();
            List <FamilyInstance> airTerminals = new List <FamilyInstance>();
            List <FamilyInstance> equipments   = new List <FamilyInstance>();

            PressureLossReportHelper helper = PressureLossReportHelper.instance;

            if (helper == null)
            {
                return;
            }

            getSectionElements(section, curves, fittings, airTerminals, equipments);

            Dictionary <string, string> fieldAndValue = new Dictionary <string, string>();

            getSectionCommonInfo(section, fieldAndValue);

            if (bForHtml)
            {
                helper.addColumns(tb, fileds.Count);
            }
            else
            {
                helper.addColumns(tb, fileds.Count + 2);
            }

            List <string> segmentVals     = new List <string>(); //segment row
            List <string> fittingVals     = new List <string>(); //fitting row
            List <string> airTerminalVals = new List <string>(); //air terminal row
            List <string> equipmentsVals  = new List <string>(); //equipment row

            if (!bForHtml)                                       //for csv, the first column is the section number
            {
                segmentVals.Add(section.Number.ToString());
                if (curves.Count < 1)
                {
                    fittingVals.Add(section.Number.ToString());
                }
                else
                {
                    fittingVals.Add(" ");
                }

                if (curves.Count < 1 && fittings.Count < 1)
                {
                    airTerminalVals.Add(section.Number.ToString());
                }
                else
                {
                    airTerminalVals.Add(" ");
                }

                if (curves.Count < 1 && fittings.Count < 1 && airTerminals.Count < 1)
                {
                    equipmentsVals.Add(section.Number.ToString());
                }
                else
                {
                    equipmentsVals.Add(" ");
                }
            }

            segmentVals.Add(helper.Domain);
            fittingVals.Add(ReportResource.fittings);

            if (helper.Domain == ReportResource.pipeDomain)
            {
                airTerminalVals.Add(ReportResource.plumbingFixtures);
            }
            else
            {
                airTerminalVals.Add(ReportResource.airTerminals);
            }
            equipmentsVals.Add(ReportResource.equipments);

            foreach (string fieldName in fileds)
            {
                PressureLossParameter PLParam = helper.getPressureLossParamByName(reportData.AvailableFields, fieldName);
                if (PLParam == null)
                {
                    continue;
                }

                if (fieldAndValue.ContainsKey(fieldName)) //section info
                {
                    if ((PLParam.GetFrom & (int)SectionMemberType.Segment) > 0)
                    {
                        segmentVals.Add(fieldAndValue[fieldName]);
                    }
                    else
                    {
                        segmentVals.Add(ReportConstants.emptyValue);
                    }

                    if ((PLParam.GetFrom & (int)SectionMemberType.Fitting) > 0)
                    {
                        fittingVals.Add(fieldAndValue[fieldName]);
                    }
                    else
                    {
                        fittingVals.Add(ReportConstants.emptyValue);
                    }

                    if ((PLParam.GetFrom & (int)SectionMemberType.AirTerminal) > 0)
                    {
                        airTerminalVals.Add(fieldAndValue[fieldName]);
                    }
                    else
                    {
                        airTerminalVals.Add(ReportConstants.emptyValue);
                    }

                    if ((PLParam.GetFrom & (int)SectionMemberType.Equipment) > 0)
                    {
                        equipmentsVals.Add(fieldAndValue[fieldName]);
                    }
                    else
                    {
                        equipmentsVals.Add(ReportConstants.emptyValue);
                    }
                }
                else if (curves.Count > 0 && (PLParam.GetFrom & (int)SectionMemberType.Segment) > 0) //read the value from first segment
                {
                    MEPCurve firstCrv = curves[0];
                    if (firstCrv == null)
                    {
                        continue;
                    }

                    string strVal = helper.getParamValue(firstCrv.get_Parameter(fieldName));
                    segmentVals.Add(strVal);
                    fittingVals.Add(ReportConstants.emptyValue);
                    airTerminalVals.Add(ReportConstants.emptyValue);
                    equipmentsVals.Add(ReportConstants.emptyValue);
                }
                else
                {
                    segmentVals.Add(ReportConstants.emptyValue);
                    fittingVals.Add(ReportConstants.emptyValue);
                    airTerminalVals.Add(ReportConstants.emptyValue);
                    equipmentsVals.Add(ReportConstants.emptyValue);
                }
            }

            //add total pressure loss
            segmentVals.Add(helper.getTotalPressureLossByType(section, SectionMemberType.Segment));
            fittingVals.Add(helper.getTotalPressureLossByType(section, SectionMemberType.Fitting));
            airTerminalVals.Add(helper.getTotalPressureLossByType(section, SectionMemberType.AirTerminal));
            equipmentsVals.Add(helper.getTotalPressureLossByType(section, SectionMemberType.Equipment));

            //add section pressure loss
            if (!bForHtml) //for csv, the last column is section pressure loss report
            {
                string sectionPL = fieldAndValue[ReportResource.sectionPressureLoss];

                segmentVals.Add(sectionPL);
                if (curves.Count < 1)
                {
                    fittingVals.Add(sectionPL);
                }
                else
                {
                    fittingVals.Add(ReportConstants.mergeValue);
                }

                if (curves.Count < 1 && fittings.Count < 1)
                {
                    airTerminalVals.Add(sectionPL);
                }
                else
                {
                    airTerminalVals.Add(ReportConstants.mergeValue);
                }

                if (curves.Count < 1 && fittings.Count < 1 && airTerminals.Count < 1)
                {
                    equipmentsVals.Add(sectionPL);
                }
                else
                {
                    equipmentsVals.Add(ReportConstants.mergeValue);
                }
            }

            if (curves.Count > 0)
            {
                helper.addRow(tb, segmentVals);
            }
            if (fittings.Count > 0)
            {
                helper.addRow(tb, fittingVals);
            }
            if (airTerminals.Count > 0)
            {
                helper.addRow(tb, airTerminalVals);
            }
            if (equipments.Count > 0)
            {
                helper.addRow(tb, equipmentsVals);
            }
        }
        /************************************************************************/

        /* use "K Coefficient" for pipe and "Loss Coefficient" for duct.
         * pressure drop to pressure loss.
         * Element ID and Mark.
         */
        /************************************************************************/
        public void upgrade2(PressureLossReportData data, int nVersion = 2)
        {
            if (data == null || data.Version >= nVersion)
            {
                return;
            }

            string fieldName = LabelUtils.GetLabelFor(BuiltInParameter.RBS_LOSS_COEFFICIENT);
            string newName   = LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_FITTING_LOSS_KFACTOR_PARAM);

            PressureLossReportHelper helper = PressureLossReportHelper.instance;

            if (helper == null)
            {
                return;
            }

            //total pressure loss table
            {
                if (data.Domain == ReportResource.pipeDomain)
                {
                    PressureLossParameter PLParam = helper.getPressureLossParamByName(data.AvailableFields, fieldName);
                    if (PLParam != null)
                    {
                        PLParam.Name = newName;
                    }
                }
            }

            string pressureDrop = LabelUtils.GetLabelFor(BuiltInParameter.RBS_PRESSURE_DROP);
            string strMark      = LabelUtils.GetLabelFor(BuiltInParameter.ALL_MODEL_MARK);

            //segment table
            {
                //use "K Coefficient" for pipe and "Loss Coefficient" for duct
                PressureLossParameter PLParam = null;
                if (data.Domain == ReportResource.pipeDomain)
                {
                    PLParam = helper.getPressureLossParamByName(data.StraightSegFields, fieldName);
                    if (PLParam != null)
                    {
                        PLParam.Name = newName;
                    }
                }

                //pressure drop to pressure loss
                PLParam = helper.getPressureLossParamByName(data.StraightSegFields, pressureDrop);
                if (PLParam != null)
                {
                    PLParam.Name = ReportResource.pressureLoss;
                }

                //Element ID and Mark
                PLParam = helper.getPressureLossParamByName(data.StraightSegFields, strMark);
                int nDisplayOrder = -1;
                if (PLParam != null)
                {
                    nDisplayOrder        = PLParam.DisplayOrder;
                    PLParam.Selected     = false;
                    PLParam.DisplayOrder = -1;

                    PLParam = helper.getPressureLossParamByName(data.StraightSegFields, ReportResource.elementId);
                    if (PLParam != null)
                    {
                        PLParam.Selected     = true;
                        PLParam.DisplayOrder = nDisplayOrder;
                    }
                }
            }

            //fitting table
            {
                //use "K Coefficient" for pipe and "Loss Coefficient" for duct
                PressureLossParameter PLParam = null;
                if (data.Domain == ReportResource.pipeDomain)
                {
                    PressureLossParameter PLParam1 = helper.getPressureLossParamByName(data.FittingFields, newName);
                    if (PLParam1 != null)
                    {
                        data.FittingFields.Remove(PLParam1);
                    }

                    PLParam = helper.getPressureLossParamByName(data.FittingFields, fieldName);
                    if (PLParam != null)
                    {
                        PLParam.Name = newName;
                    }
                }

                //Pressure Drop to Pressure Loss
                PLParam = helper.getPressureLossParamByName(data.FittingFields, pressureDrop);
                if (PLParam != null)
                {
                    PLParam.Name = ReportResource.pressureLoss;
                }

                //Element ID and Mark
                PLParam = helper.getPressureLossParamByName(data.FittingFields, strMark);
                int nDisplayOrder = -1;
                if (PLParam != null)
                {
                    nDisplayOrder        = PLParam.DisplayOrder;
                    PLParam.Selected     = false;
                    PLParam.DisplayOrder = -1;

                    PLParam = helper.getPressureLossParamByName(data.FittingFields, ReportResource.elementId);
                    if (PLParam != null)
                    {
                        PLParam.Selected     = true;
                        PLParam.DisplayOrder = nDisplayOrder;
                    }
                }
            }

            data.Version = nVersion;
            PressureLossReportDataManager.Instance.save(data);
        }
        private bool getSegmentInfo(MEPSection section, DataTable segmentTB, bool forHTML = false)
        {
            if (segmentTB == null || section == null)
            {
                return(false);
            }

            PressureLossReportHelper helper = PressureLossReportHelper.instance;

            if (helper == null || helper.ReportData == null)
            {
                return(false);
            }

            //get fields from reportData
            List <string> segmentFields = new List <string>();

            getFields(segmentFields);

            if (forHTML)
            {
                helper.addColumns(segmentTB, segmentFields.Count);
            }
            else
            {
                helper.addColumns(segmentTB, segmentFields.Count + 2);
            }

            List <MEPCurve> curves = new List <MEPCurve>();

            SectionsInfo.getSectionElements(section, curves, null, null, null);
            if (curves.Count < 1)
            {
                return(false);
            }

            int nIndex = 0;

            foreach (MEPCurve crv in curves)
            {
                List <string> paramVals = new List <string>();
                if (!forHTML)
                {
                    if (nIndex == 0)
                    {
                        paramVals.Add(section.Number.ToString());
                    }
                    else
                    {
                        paramVals.Add(" ");
                    }
                }

                foreach (string fieldName in segmentFields)
                {
                    PressureLossParameter PLParam = helper.getPressureLossParamByName(helper.ReportData.StraightSegFields, fieldName);
                    if (PLParam == null)
                    {
                        continue;
                    }

                    string strVal = ReportConstants.emptyValue;
                    if (((PLParam.GetFrom & (int)SectionMemberType.Section) > 0))
                    {
                        strVal = SectionsInfo.getSectionInfoByParamName(section, fieldName, PLParam.GetFrom, crv.Id);
                    }
                    else if ((PLParam.GetFrom & (int)SectionMemberType.Segment) > 0)
                    {
                        if (helper.Domain == ReportResource.pipeDomain &&
                            fieldName == LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_FLOW_STATE_PARAM))
                        {
                            int nVal = crv.get_Parameter(fieldName).AsInteger();
                            strVal = LabelUtils.GetLabelFor((Autodesk.Revit.DB.Plumbing.PipeFlowState)nVal, helper.Doc);
                        }
                        else if ((fieldName == LabelUtils.GetLabelFor(BuiltInParameter.RBS_PIPE_SIZE_FORMATTED_PARAM) ||
                                  fieldName == LabelUtils.GetLabelFor(BuiltInParameter.RBS_DUCT_SIZE_FORMATTED_PARAM)) &&
                                 ((BuiltInCategory)crv.Category.Id.IntegerValue == BuiltInCategory.OST_FlexDuctCurves ||
                                  (BuiltInCategory)crv.Category.Id.IntegerValue == BuiltInCategory.OST_FlexPipeCurves))
                        {
                            //for flex duct/pipe, no size parameter, using diameter?
                            if (helper.Domain == ReportResource.pipeDomain)
                            {
                                strVal = helper.getParamValue(crv.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM));
                            }
                            else
                            {
                                //TBD: need to check round or rect
                                strVal = helper.getParamValue(crv.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM));
                            }
                        }
                        else if (fieldName == ReportResource.elementId)
                        {
                            strVal = crv.Id.ToString();
                        }
                        else
                        {
                            strVal = helper.getParamValue(crv.get_Parameter(fieldName));
                        }
                    }
                    else if ((PLParam.GetFrom & (int)SectionMemberType.Type) > 0)
                    {
                        strVal = getSegmentTypeInfoByParamName(crv, fieldName);
                    }

                    paramVals.Add(strVal);
                }

                if (!forHTML) //for csv, the last column is section pressure loss report
                {
                    string strVal = ReportConstants.mergeValue;
                    if (nIndex == 0)
                    {
                        strVal = helper.getTotalPressureLossByType(section, SectionMemberType.Segment);
                    }

                    paramVals.Add(strVal);
                }

                nIndex++;

                helper.addRow(segmentTB, paramVals);
            }

            return(true);
        }