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


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

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



/*---------------------------Function Prototypes-----------------------------*/
ProError UserPickPosition ();
void UserFreeNoteSetup();

/*****************************************************************************\
Function : UserNoteCreate() 
Purpose :  Create a drawing note
\*****************************************************************************/
ProError UserNoteCreate()
{
    ProError    status;
    ProMdl		p_draw;
    ProDtlnote 	note;
    ProCharLine     	text;
    wchar_t     	**w_text = NULL;
    ProPoint3d		pos;
    ProSelection  *leaders;
    int			n_leaders;
    ProFileName WMSGFIL = { 'm','s','g','_','u','g','d','w','g','.','t','x','t','\0' };
    int nTxt = 0;
    ProView noteView=NULL;
    int ii = 0;

    /*------------------------------------------------------------*\
    Get the current model
    \*------------------------------------------------------------*/
    status = ProMdlCurrentGet(&p_draw);
    ERROR_CHECK("UserNoteCreate", "ProMdlCurrentGet", status);
    if (status != PRO_TK_NO_ERROR) return(status);

    /*----------------------------------------------------------*\
    Ask the user for the note position.
    \*----------------------------------------------------------*/
    status = UserPickPosition(WMSGFIL, "Pick the position of the new note.", pos);
    ERROR_CHECK("UserNoteCreate", "UserPickPosition", status);
    if (status != PRO_TK_NO_ERROR) return(status);

    /*----------------------------------------------------------*\
    Ask the user to enter multiple texts. 
    Each note line will contain two texts with alternate text styles.
    \*----------------------------------------------------------*/
    while (1)
    {
        ProLine buffer;
        wchar_t* ptr = 0;
        status = ProMessageDisplay(WMSGFIL, "USER %0s",
                "Enter note text [QUIT] : ");
        ERROR_CHECK("UserNoteCreate", "ProMessageDisplay", status);

        status = ProMessageStringRead(PRO_LINE_SIZE, buffer);
        ERROR_CHECK("UserNoteCreate", "ProMessageStringRead", status);
        if (status != PRO_TK_NO_ERROR)
            break;

        if (w_text == NULL)
            ProArrayAlloc(0, sizeof(wchar_t*), 1, (ProArray*)&w_text); 

        ProArrayObjectAdd((ProArray*)&w_text, PRO_VALUE_UNUSED, 1, &ptr);

        ProArrayAlloc(PRO_LINE_SIZE, sizeof(wchar_t), 1, (ProArray*)&w_text[nTxt]);
        ProWstringCopy(buffer, w_text[nTxt], PRO_VALUE_UNUSED);
        nTxt++;
    }

    if (w_text == NULL)
        return PRO_TK_BAD_INPUTS;
      
    /*----------------------------------------------------------*\
    Ask the user to pick the leader points (edges of models in
    drawing views).
    \*----------------------------------------------------------*/
    status = ProMessageDisplay(WMSGFIL, "USER %0s", "Select leader points");
    ERROR_CHECK("UserNoteCreate","ProMessageDisplay",status);

    ProSelect ("edge", -1, NULL, NULL, NULL, NULL, &leaders, &n_leaders);

    if (n_leaders > 0)
        ProSelectionViewGet(leaders[0], &noteView);
    /*----------------------------------------------------------*\
    Add the note to the drawing.
    \*----------------------------------------------------------*/
    UserFreeNoteSetup ( p_draw, pos, w_text, n_leaders, leaders,noteView, &note );

    status = ProAnnotationShow(&note,NULL, noteView);
    ERROR_CHECK("UserNoteCreate","ProAnnotationShow",status);
    if (status != PRO_TK_NO_ERROR) return(PRO_TK_GENERAL_ERROR);

    status = ProDrawingtreeRefresh(p_draw, PRO_VALUE_UNUSED);
   
    for (ii = 0; ii < nTxt; ii++)
    {
        ProArrayFree((ProArray*)&w_text[ii]);
    }
    ProArrayFree((ProArray*)&w_text);

    return(PRO_TK_NO_ERROR);
}

/*===============================================================*\
    Function that gives the default text height for the
    specified drawing
\*===============================================================*/
ProError UserTextHeightScale (ProMdl p_draw, double * height)
{
    int 	cur_sheet;
    ProName   	w_size;
    ProMatrix   matrix;
    ProError    err;

    /*----------------------------------------------------------*\
    Scale text height 
    \*----------------------------------------------------------*/  

    err = ProDrawingCurrentSheetGet(p_draw, &cur_sheet);
    err = ProDrawingSheetTrfGet(p_draw, cur_sheet, w_size, matrix);
    ERROR_CHECK("UserTextDefaultHeight","ProDrawingSheetTrfGet", err);
    if (PRO_TK_NO_ERROR != err) return (PRO_TK_GENERAL_ERROR);

   *height /= matrix[0][0]; /* for unit conversion */
    return (PRO_TK_NO_ERROR);

}
ProTextStyle UserCreateTextStyle(wchar_t* font, double height, double width, double slant, double thickness)
{
    ProError err;
    ProTextStyle style;
    int fontid = -1;

    err = ProTextStyleAlloc(&style);
    if (font != NULL)
        err = ProTextStyleFontSet(style, font);

    err = ProTextStyleHeightSet(style, height);
    err = ProTextStyleWidthSet(style, width);
    err = ProTextStyleSlantAngleSet(style, slant);
    err = ProTextStyleThicknessSet(style, thickness);

    return style;
}
/*===============================================================*\
    Function that sets up the C structure for a free note with
    parametric leaders
\*===============================================================*/
void UserFreeNoteSetup(
	ProMdl		p_draw,
	ProVector       pos,
	wchar_t**         texts,
	int           	n_leaders,
	ProSelection   	*attach_geom,
    ProView         noteView,
	ProDtlnote      *p_note)
{
    ProDtlnotedata notedata;
    ProDtlnoteline dtl_line;
    ProDtlnotetext dtl_text;
    ProLine wtext;
    double height;
    ProColor color;
    ProDtlattach attachment, *leaders;
    ProError err = PRO_TK_NO_ERROR;
    int l;
    int n_txts = 0,ii=0,jj=0;
    ProTextStyle style1, style2,style3;
    ProDtlnoteline* lines=0;
    int nLines = 0;
   
    /*----------------------------------------------------------*\
    Claim and initialize the note record.
    \*----------------------------------------------------------*/
    ProDtlnotedataAlloc(p_draw, &notedata);

    ProArraySizeGet((ProArray)texts, &n_txts);
    if (n_txts < 1)
        return;

    /*----------------------------------------------------------*\     
     Create two text style object for alternate texts in line.
   \*----------------------------------------------------------*/
    height = -1.0;
    style1 = UserCreateTextStyle(L"cgomg", height, 0.8, 0, 0.8);
    height = 0.19;
    err = UserTextHeightScale(p_draw, &height);
    style2 = UserCreateTextStyle(NULL, height, 0.2, 15, 0.2);

    for (ii = 0, jj = 0; ii < n_txts; ii++, jj++)
    {
        if (jj % 2 == 0)
            ProDtlnotelineAlloc(&dtl_line);

        /*----------------------------------------------------------*\
        Add a two text record to the text line.
        \*----------------------------------------------------------*/
        ProDtlnotetextAlloc(&dtl_text);

        /*----------------------------------------------------------*\
        Set up the alternate text with different text style.
        \*----------------------------------------------------------*/
        if (jj % 2 == 0)           
            err = ProDtlnotetextStyleSet(dtl_text, style1); 
        else
            err = ProDtlnotetextStyleSet(dtl_text, style2);
       
        err = ProDtlnotetextStringSet (dtl_text, texts[ii]);
        
        err = ProDtlnotelineTextAdd(dtl_line, dtl_text);

        if (jj % 2 != 0 || n_txts == 1)
            err = ProDtlnotedataLineAdd(notedata, dtl_line);         
    }

    /*----------------------------------------------------------*\
    Set the entire note to be the default color for text.
    \*----------------------------------------------------------*/
    err = ProTextStyleAlloc(&style3);
    color.method = PRO_COLOR_METHOD_TYPE;
    color.value.type = PRO_COLOR_LETTER;
    err = ProTextStyleColorSetWithDef(style3, &color);
    err = ProDtlnotedataTextStyleSet(notedata, style3);

    /*----------------------------------------------------------*\
    Set the attachment to be FREE at the specified screen
    coordinates. Associate it with leader selection view.
    \*----------------------------------------------------------*/   
    err = ProDtlattachAlloc(PRO_DTLATTACHTYPE_FREE, noteView, pos, NULL, &attachment);
    err = ProDtlnotedataAttachmentSet(notedata, attachment);
    /*----------------------------------------------------------*\
    Copy the selected leader points as PARAMETRIC leaders.
    \*----------------------------------------------------------*/
    err = ProArrayAlloc (n_leaders, sizeof (ProDtlattach), 1, (ProArray*)&leaders);

    for (l = 0; l < n_leaders; l++)
    {         
         err = ProDtlattachAlloc(PRO_DTLATTACHTYPE_PARAMETRIC, NULL, NULL, attach_geom[l], &leaders[l]);         
    }

    err = ProDtlnotedataLeadersSet(notedata, leaders);

    for (l = 0; l < n_leaders; l++)
      err = ProDtlattachFree (leaders[l]);
    err = ProArrayFree ((ProArray*)&leaders);

    err = ProDtlnoteCreate(p_draw, NULL, notedata, p_note);
    err = ProDtlnotedataFree(notedata);
    ProTextStyleFree(&style1);
    ProTextStyleFree(&style2);
    ProTextStyleFree(&style3);
}