/*****************************************************************************\
FILE    : UgViewCreate.c
PURPOSE : Pro/TOOLKIT User Guide - drawing view creation
HISTORY..
DATE      BUILD   AUTHOR    MODIFICATIONS
04-Dec-97 H-02-02 Philippe  $$1    Created
\*****************************************************************************/
/*-------------------------- Pro/Develop includes ---------------------------*/
#include <prodevelop.h>
#include <select3d.h>

/*-------------------------- Pro/Toolkit includes ---------------------------*/
#include <ProToolkit.h>
#include <ProMdl.h>
#include <ProCsys.h>

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



/*-------------------------- Function Prototypes ----------------------------*/
ProError UserSelectViewType (char * selected);
ProError UserSelectExplodeState (int * exploded);
ProError UserPickPosition ();

/*================================================================*\
FUNCTION  : UserViewCreate
PURPOSE   : Creates both general and projection type drawing views.
\*================================================================*/
int UserViewCreate ()
{
    /* Current Drawing Variables */
    ProMdl		p_draw;
    int 		num_sheets, sheet_num;

    /* Created view variables */
    Pro_draw_view       view_data;
    char		view_type[PRO_NAME_SIZE];
    char		expl_state[PRO_NAME_SIZE];
    ProPoint3d		position;
    int 		view_id;

    /* View Selection Variables  for Projection View Creation*/
    Select3d		*view_sel;
    Object_element	sub, *ref;
    int			sel_num;

    /* Model Variables for General View Creation */
    ProMdl		p_model;
    ProMdlType		type;
    ProName		name;

    /* Csys variables for General View Creation */
    ProCsys           	p_csys;
    ProGeomitemdata     *csys_data;
    ProName		csys_name;
    double              matrix[4][4];

    /* General use variables */
    int                 status;
    int 		anint;
    int                 i_range[2];
    double		d_range[2];
    char                astr[PRO_LINE_SIZE];
    int 		win_id;

    ProFileName WMSGFIL = {'m','s','g','_','u','g','d','w','g','.','t','x','t','\0'};
    /*------------------------------------------------------------*\
      Get the current model
    \*------------------------------------------------------------*/
    status = ProMdlCurrentGet(&p_draw);
    ERROR_CHECK("UserViewCreate","ProMdlCurrentGet",status);
    if (status != PRO_TK_NO_ERROR) return(status);

    /*------------------------------------------------------------*\
      Prompt for the sheet to insert to
    \*------------------------------------------------------------*/
    num_sheets = prodrw_number_sheets ( (Prohandle) p_draw);
    ERROR_CHECK("UserViewCreate","prodrw_number_sheets",(num_sheets<=0));
    if (num_sheets<=0) return (PRO_TK_GENERAL_ERROR);

    i_range[0] = 1;
    i_range[1] = num_sheets;
    sprintf (astr, "Enter sheet number [1-%d] [CUR] : ", num_sheets);
    status = ProMessageDisplay(WMSGFIL, "USER %0s", astr);
    ERROR_CHECK("UserViewCreate","ProMessageDisplay",status);

    status = ProMessageIntegerRead(i_range, &sheet_num);
    ERROR_CHECK("UserViewCreate","ProMessageIntRead",status);
    if (status != PRO_TK_NO_ERROR)
      {
        sheet_num = prodrw_get_current_sheet ( (Prohandle) p_draw);
        ERROR_CHECK("UserViewCreate","prodrw_get_current_sheet",(sheet_num<=0));
       	if (sheet_num<=0) return (PRO_TK_GENERAL_ERROR);
      }

    /*------------------------------------------------------------*\
      get the type of view to create (Projection or General)
      (warning : should test if there is a view on this sheet first)
    \*------------------------------------------------------------*/
    status = ProMessageDisplay(WMSGFIL, "USER %0s",
				"Select the type of view to create ");
    ERROR_CHECK("UserViewCreate","ProMessageDisplay",status);

    status = UserSelectViewType(view_type);
    ERROR_CHECK("UserViewCreate","UserSelectViewType",status);
    if (status != PRO_TK_NO_ERROR) return(status);
    
    /*------------------------------------------------------------*\
      For a Projection, do the following
    \*------------------------------------------------------------*/
    if (!strcmp(view_type,"-Projection"))
      {
        view_data.type = PRODRWVIEW_PROJECTION;

        /*---------------------------------------------------------*\
	  Get the view to project
	\*---------------------------------------------------------*/
        status = ProMessageDisplay (WMSGFIL,"USER %0s", 
				    "Select a parent view.");
        ERROR_CHECK ("UserViewCreate","ProMessageDisplay",status);
  		
	sel_num = pro_select("dwg_view", 1, &view_sel, NULL,NULL);
	ERROR_CHECK("UserViewCreate","pro_select", (sel_num<=0));
	if (sel_num <0) return (PRO_TK_GENERAL_ERROR);
	else if (sel_num =0) return (PRO_TK_USER_ABORT);
 
	sub.type = SEL_DWG_VIEW;
 	sub.ptr = view_sel[0].view_ptr;
	sub.id = -1;
	status = pro_element_info ((Prohandle) p_draw, &sub, PRO_IDENTIFY,
					 -1, &ref);
        ERROR_CHECK("UserViewCreate","pro_element_info", (status <=0));
        if (status <=0) return (PRO_TK_GENERAL_ERROR);

	view_data.form.projection.view_id = ref[0].id;

        /*---------------------------------------------------------*\
	  Obtain the type of the model in that view 
	\*---------------------------------------------------------*/
	p_model = (ProMdl) prodrw_get_view_model( (Prohandle) p_draw,
						  ref[0].id);
	ERROR_CHECK ("UserViewCreate","prodrw_get_view_model",
			(p_model == 0));

	status = ProMdlTypeGet(p_model, &type);
        ERROR_CHECK ("UserViewCreate","ProMdlTypeGet",status);
    	if (status != PRO_TK_NO_ERROR) return(status);

        /*---------------------------------------------------------*\
	  If the model is an assembly, explode ?
	\*---------------------------------------------------------*/
	if ( type == PRO_MDL_ASSEMBLY)
	  {
	    status =UserSelectExplodeState(&(view_data.form.projection.exploded));
	    if (status != PRO_TK_NO_ERROR) return (status);
	  }
        else view_data.form.projection.exploded = 0;
	  
        /*---------------------------------------------------------*\
	  Get the position where to put the view
	\*---------------------------------------------------------*/
	status = UserPickPosition(WMSGFIL, "Select position for view creation",
				   view_data.form.projection.pos);	
	if (status != PRO_TK_NO_ERROR) return (status);
      }
    /*------------------------------------------------------------*\
      For a General view, do the following
    \*------------------------------------------------------------*/
    else if (!strcmp(view_type, "-General"))
      {
        view_data.type = PRODRWVIEW_GENERAL;
        view_data.form.general.sheet_num = sheet_num;

        /*---------------------------------------------------------*\
	  Prompt the user for the model to add to the drawing
	\*---------------------------------------------------------*/
        status = UserUtilNameTypeGet(WMSGFIL, name, &type );
        ERROR_CHECK("UserViewCreate","UserUtilNameTypeGet",status);
        if (status != PRO_TK_NO_ERROR) return(PRO_TK_GENERAL_ERROR);

        status = ProMdlRetrieve(name, type, (&p_model));
        ERROR_CHECK("UserViewCreate","ProMdlRetrieve",status);
        if (status != PRO_TK_NO_ERROR) return(PRO_TK_E_NOT_FOUND);

        /*---------------------------------------------------------*\
	  Add it to the drawing and to the drawing_view_data
	\*---------------------------------------------------------*/
        status = prodrw_add_drawing_model ((Prohandle) p_draw,
                                           (Prohandle) p_model);
	ERROR_CHECK("UserViewCreate","prodrw_add_drawing_model",
			(status != PRODRW_ADD_MODEL_SUCCESS));
	if ((status != PRODRW_ADD_MODEL_SUCCESS) &&
	    (status != PRODRW_ADD_MODEL_EXIST)) 
		return (PRO_TK_GENERAL_ERROR);
 
        view_data.form.general.model = (Prohandle) p_model;

        /*---------------------------------------------------------*\
          If the model is an assembly, explode ?
        \*---------------------------------------------------------*/
        if ( type == PRO_MDL_ASSEMBLY)
	  {
            status = UserSelectExplodeState(&(view_data.form.general.exploded));
	    ERROR_CHECK("UserViewCreate","UserSelectExplodeState",status);
	    if (status != PRO_TK_NO_ERROR) return (status);
	  }	
  	else view_data.form.general.exploded = 0;

        /*---------------------------------------------------------*\
	  Get the position where to put the view
	\*---------------------------------------------------------*/
	status = UserPickPosition(WMSGFIL,"Select position for view creation",
				  view_data.form.general.pos);	
	ERROR_CHECK("UserViewCreate","UserSelectExplodeState",status);
	if (status != PRO_TK_NO_ERROR) return (status);

        /*---------------------------------------------------------*\
	  View Scale
	\*---------------------------------------------------------*/
        status = ProMessageDisplay (WMSGFIL, "USER %0s", 
				    "Enter view scale factor [CR=default]:");
	ERROR_CHECK("UserViewCreate","ProMessageDisplay",status);
	
	status = ProMessageDoubleRead(d_range,&view_data.form.general.scale);
	ERROR_CHECK("UserViewCreate","ProMessageDoubleRead",status);
	if (status != PRO_TK_NO_ERROR) view_data.form.general.scale = 0.0;
	
        /*---------------------------------------------------------*\
	  Orientation
	\*---------------------------------------------------------*/
	ProUtilMatrixCopy (NULL, view_data.form.general.orient); 
	status = ProMessageDisplay(WMSGFIL,"USER %0s",
	    "Enter model csys name to define view orientation [CR=default]:");
	ERROR_CHECK("UserViewCreate","ProMessageDisplay",status);
	
	status = ProMessageStringRead (PRODEV_NAME_SIZE, csys_name);
	ERROR_CHECK("UserViewCreate","ProMessageStringRead",status);
	
	if (status == PRO_TK_NO_ERROR)
	  {
	    status = ProUtilCsysFind((Prohandle) p_model, csys_name, &p_csys);
	    ERROR_CHECK("UserViewCreate","ProUtilCsysFind",status);
	    
	    if (status == PRO_TK_NO_ERROR)
	      {
		status = ProCsysDataGet (p_csys, &csys_data);
		ERROR_CHECK("UserViewCreate","ProCsysDataGet",status);
		
		ProUtilTransfToVectors( matrix,
				  	csys_data->data.p_csys_data->x_vector,
					csys_data->data.p_csys_data->y_vector,
				  	csys_data->data.p_csys_data->z_vector,
				  	csys_data->data.p_csys_data->origin);
		
		status = ProGeomitemdataFree(&csys_data);
		ERROR_CHECK("UserViewCreate","ProGeomitemdataFree",status);
		
		ProUtilMatrixInvert(matrix, view_data.form.general.orient);
	      }
	  }
     }     

    else
      return (PRO_TK_GENERAL_ERROR);

   status = prodrw_create_view (p_draw, &view_data, &view_id);
   ERROR_CHECK("UserViewCreate","prodrw_create_view",
	       status != PRODEV_NO_ERROR);
    
   if (status != PRODEV_NO_ERROR)
     {
     	sprintf(astr, "Error %d in UserViewCreate", status);
 	status = ProMessageDisplay(WMSGFIL, "USER %0s", astr);
	ERROR_CHECK ("UserViewCreate","ProMessageDisplay",status);
	return (PRO_TK_GENERAL_ERROR);
     }
 
   strcpy(astr, "View Created Successfully");
   status = ProMessageDisplay(WMSGFIL, "USER %0s", astr);
   ERROR_CHECK ("UserViewCreate","ProMessageDisplay",status);
   
   /*------------------------------------------------------------*\
     Update the changes by repainting the window
   \*------------------------------------------------------------*/
   status = ProWindowCurrentGet(&win_id);
   ERROR_CHECK("UserViewCreate","ProWindowCurrentGet",status);
   if (status != PRO_TK_NO_ERROR) return (status);
 
   status = ProWindowRepaint (win_id);
   ERROR_CHECK("UserViewCreate","ProWindowRepaint",status);
   return (status);
}


/*=====================================================================*\
			HELPER FUNCTIONS
\*=====================================================================*/
/*================================================================*\
FUNCTION  : UserSelectViewType
PURPOSE   : Select Projection or General
\*================================================================*/
ProError UserSelectViewType (char * selected)
{
  int 		i, status;
  ProName	wtitle;
  wchar_t    ** buttons; 
  wchar_t    ** selection;
  int 		num;

  ProStringToWstring(wtitle, "UG View Type"); 

  buttons =  (wchar_t **) calloc(3, sizeof(wchar_t *));
  for (i=0 ; i<3 ; i++)
	buttons[i] = (wchar_t *) calloc(1, sizeof(ProName));
  ProStringToWstring(buttons[0], "-Projection");
  ProStringToWstring(buttons[1], "-General");
  ProStringToWstring(buttons[2], "");

  status = ProMenuStringsSelect (wtitle, buttons, 1, NULL, &selection, &num);
  if (status != PRO_TK_NO_ERROR) return (status);

  ProWstringToString(selected, selection[0]);

  return (PRO_TK_NO_ERROR); 
}


/*================================================================*\
FUNCTION  : UserSelectExplodeState
PURPOSE   : Select NotExploded or Exploded
\*================================================================*/
ProError UserSelectExplodeState (int * explode)
{
  int           i, status;
  ProName       wtitle; 
  wchar_t    ** buttons;
  wchar_t    ** selection;
  int           num;
  ProName	WMSGFIL;
  char          selected[PRO_NAME_SIZE];

  ProMessageDisplay(WMSGFIL, "USER %0s", 
		"Select explode state of the view to create ");

  ProStringToWstring(wtitle, "UG Explode");

  buttons =  (wchar_t **) calloc(3, sizeof(wchar_t *));
  for (i=0 ; i<3 ; i++)
        buttons[i] = (wchar_t *) calloc(1, sizeof(ProName));
  ProStringToWstring(buttons[0], "-Not Exploded");
  ProStringToWstring(buttons[1], "-Exploded");
  ProStringToWstring(buttons[2], "");

  status = ProMenuStringsSelect (wtitle, buttons, 1, NULL, &selection, &num);
  if (status != PRO_TK_NO_ERROR) return (status);

  ProWstringToString(selected, selection[0]);

  if (!strcmp(selected, "-Exploded"))
     (*explode) = 1;
  else
     (*explode) = 0;

  return (PRO_TK_NO_ERROR);
}

