/*
	Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/


/*---------------------- Pro/Toolkit Includes ------------------------*/
#include <ProToolkit.h>
#include <ProFaminstance.h>
#include <ProFamtable.h>
#include <ProDimension.h>
#include <ProAnnotation.h>
#include <ProDrawing.h>
#include <ProUtil.h>
#include <ProMessage.h>

/*---------------------- Application Includes ------------------------*/
#include <TestError.h>

#define EPSM6 1.0e-6

/*---------------------- Function Prototypes -------------------------*/
ProError user_Family_Diffs();
ProError user_family_diffs ();

/*------------------------- Global Data ------------------------------*/
static ProFileName msgfil;
ProError user_Family_Diffs()
{
    ProDrawing   drawing;
    ProSelection *sel;
    ProError     err;
    int          n_sel;

    err = ProMdlCurrentGet((ProMdl*)&drawing);
    ProStringToWstring( msgfil, "msg_ugfamtab.txt" );

/*-----------------------------------------------------------*\
    Ask the user to select a drawing view.
\*-----------------------------------------------------------*/
    err = ProMessageDisplay (msgfil, "USER Select the view");
    while (ProSelect ("dwg_view", 1, NULL, NULL, NULL,  NULL, &sel, &n_sel)== PRO_TK_NO_ERROR)
    {
      ProView view;

      if (n_sel < 1) break;
/*-----------------------------------------------------------*\
        Call the function to display family differences for
        this view.
\*-----------------------------------------------------------*/
        err = ProSelectionViewGet(sel[0], &view);
        user_family_diffs (drawing, view);
    }
    
    return ( PRO_TK_NO_ERROR );
}

typedef struct user_fam_diff_data
{
   ProMdl gen_model;
   ProFaminstance *fam_instance;
   ProMdl          inst_model;
   ProView         view;
} UserFamDiffData;

ProError user_fam_diff_action(ProFamtableItem   *famtable_item,
                              ProError           status,
                              ProAppData         app_data)
{
  ProParamvalue inst_value;
  ProParamvalueType val_type;
  ProError err;
  UserFamDiffData *p_diffdata = (UserFamDiffData*)app_data;
  ProDimension dimension;
  double       generic_val, instance_val, diff, diff1;

  ProFaminstance *fam_instance = p_diffdata->fam_instance;
  ProMdl         gen_model = p_diffdata->gen_model;
  ProMdl         inst_model = p_diffdata->inst_model;
  ProView        view = p_diffdata->view;

  /*-----------------------------------------------------------*\
         If the column is not a DIMENSION, skip it.
  \*-----------------------------------------------------------*/
  if (PRO_FAM_DIMENSION != famtable_item->type)
    return PRO_TK_NO_ERROR;

  /*-----------------------------------------------------------*\
         Read the values in this column for the generic
         and for the instance. If they are the same, or the
         instance has an asterisk, skip it.
  \*-----------------------------------------------------------*/
  err = ProFamtableItemToModelitem(famtable_item, &dimension);
  dimension.owner = gen_model;
  err = ProFaminstanceValueGet (fam_instance, famtable_item, &inst_value);

  /*-----------------------------------------------------------*\
         Skip non-double values.
  \*-----------------------------------------------------------*/
  if (PRO_PARAM_DOUBLE != inst_value.type)
    return PRO_TK_NO_ERROR;

  err = ProDimensionValueGet(&dimension, &generic_val);
  if (PRO_TK_NO_ERROR != err) return err;
  err = ProParamvalueValueGet(&inst_value, PRO_PARAM_DOUBLE, &instance_val);
  if (PRO_TK_NO_ERROR != err) return err;

  /*-----------------------------------------------------------*\
         Read the values in this column for the generic
         and for the instance. If they are the same, or the
         instance has an asterisk, skip it.
  \*-----------------------------------------------------------*/
  diff = instance_val - generic_val;
  if (diff < 0.) diff = -diff;
  if (diff < EPSM6)
    return PRO_TK_NO_ERROR;

  dimension.owner = inst_model;
  err = ProAnnotationDisplay(&dimension, NULL, NULL, view);
  
  /*-----------------------------------------------------------*\
         If the dimension has already shown - no error. 
  \*-----------------------------------------------------------*/
  if (PRO_TK_NO_CHANGE == err)
    err = PRO_TK_NO_ERROR;

  return err;
}

ProError user_family_diffs (drawing, view)
 ProDrawing  drawing;
 ProView  view;
{

    ProSolid          inst_model, gen_model;
    ProError          err;     
    ProFamtable       famtable;
    ProFaminstance    fam_instance;
    UserFamDiffData   diffdata;
	ProMdlName        modelName;

/*-----------------------------------------------------------*\
    Get the model in the selected view.
\*-----------------------------------------------------------*/
    err = ProDrawingViewSolidGet(drawing, view, &inst_model);

	err = ProMdlMdlnameGet(inst_model, modelName);
    
    

/*-----------------------------------------------------------*\
    Get the generic model, and complain if there isn't one. 
\*-----------------------------------------------------------*/

    err = ProFaminstanceGenericGet(inst_model, PRO_B_TRUE, (ProMdl*)&gen_model);
    if (PRO_TK_NO_ERROR != err)
    {
          ProMessageDisplay (msgfil, 
           "USER This view does not contain a family table instance");
          return ( err );
    }

    err = ProFamtableInit(gen_model, &famtable);
    err = ProFamtableCheck (&famtable);

    err = ProFaminstanceInit(modelName, &famtable, &fam_instance);

    diffdata.gen_model    = gen_model;
    diffdata.fam_instance = &fam_instance;
    diffdata.inst_model   = inst_model;
    diffdata.view         = view;

    err = ProFamtableItemVisit(&famtable, (ProFamtableItemAction)user_fam_diff_action, 
                               (ProFamtableItemFilter)NULL, (ProAppData)&diffdata);
    return ( PRO_TK_NO_ERROR );
}