/******************************************************************************/
/***                                                                        ***/
/***  ReadTemp                                                              ***/
/***                                                                        ***/
/***  Reads a templates definition, and creates a 'C' structre defining the ***/
/***  window to be used,                                                    ***/
/***                                                                        ***/
/***                                                                        ***/
/***                                                                        ***/
/***  Written by N.Critchell, Acorn Computers            11th October 1991  ***/
/***                                   Updated by N.C.    12th August 1992  ***/
/***                                                                        ***/
/******************************************************************************/

 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
 #include <string.h>

 #include "kernel.h"


#define TRUE                    1
#define FALSE                   0

#define Wimp_OpenTemplate       0x400D9
#define Wimp_CloseTemplate      0x400DA
#define Wimp_LoadTemplate       0x400DB





static char template_filename[] = "<SPReadTemps$DirSource>.SPTemps"; 
static char window_def_filename[] = "<SPReadTemps$DirDestination>.WindDef"; 



int MakeWindowDefinitionStructure(void);

int  LoadNextWindowDefinition(char *, char *, int, int *, int);
int  Open_TemplateFile(char *);
void Close_TemplateFile(void);
void CreateNewFile(char *);
int  get_number_of_icons(char *);
void Output_Data(FILE *, char *, int);
void print_hex(FILE *, int);
void Set_Deferred_Data_Offsets(char *, char *, char *, int);








/******************************************************************************/
/***  main()                                                                ***/
/***                                                                        ***/
/***  This program reads a template file and creates a file containing a    ***/
/***  a 'C' structure for the definition of the window. This definition can ***/
/***  the be compile with a 'C' program to open a window which can not be   ***/
/***  altered by a user.                                                    ***/
/***                                                                        ***/
/***  The program will make a structure for every window definition begining***/
/***  Box.                                                                  ***/
/******************************************************************************/

int main()
    {
    if (Open_TemplateFile(template_filename) == TRUE)
        {
        CreateNewFile(window_def_filename);

        while(MakeWindowDefinitionStructure());

        Close_TemplateFile();
        }
    else printf("Can not open template file\n");

    exit(0);
    }







/******************************************************************************/
/***                                                                        ***/
/***  MakeWindowDefinitionStructure()                                       ***/
/***                                                                        ***/
/***  Will create a complete structure for the next window definition, this ***/
/***  routine will return TRUE if completed, FALSE if not completed. (FALSE ***/
/***  is returned if no more window definitons can be found).               ***/
/***                                                                        ***/
/******************************************************************************/

int MakeWindowDefinitionStructure()
    {
    char TemplateBuffer [10240];
    char IndiectedIconsBuffer [20480];
    static int current_window = 0;
    static int window_count = 0;
    int  defered_data_size;
    int  deferred_data_offset;
    int  loop;
    char *current_icon_data;
    FILE *handle;

    window_count++;          
    defered_data_size = LoadNextWindowDefinition(TemplateBuffer, IndiectedIconsBuffer, 20480, &current_window, window_count);
    if (current_window !=0)
        {

        if ((handle = fopen(window_def_filename, "a")) != NULL)
            {
            printf("Creating window definition %d.\n", window_count);
            fprintf(handle, "struct window_%d\n", window_count);
            fprintf(handle, "       {\n");
            fprintf(handle, "       WINDOW        win_info;\n");
            if (get_number_of_icons(TemplateBuffer) >0)
                fprintf(handle, "       ICON          icon[%d];\n", get_number_of_icons(TemplateBuffer));
            if (defered_data_size > 0)
                fprintf(handle, "       int           deferred[%d];\n", (defered_data_size/4) +2);
            fprintf(handle, "       } window_%d =\n", window_count);  
            fprintf(handle, "       {\n");

            deferred_data_offset = 88 + (32 * get_number_of_icons(TemplateBuffer));

            /******************************************************************************************************/
            /***      Write out window definition, changing any deferred data offsets                           ***/
            /******************************************************************************************************/           
            Set_Deferred_Data_Offsets(TemplateBuffer + 56, TemplateBuffer + 72, IndiectedIconsBuffer, deferred_data_offset);
            Output_Data(handle, TemplateBuffer, 88);


            /******************************************************************************************************/
            /***      Write out Icon definitions, changing any deferred data offsets                            ***/
            /******************************************************************************************************/           
            current_icon_data = TemplateBuffer + 88;
            for(loop=1; loop<=get_number_of_icons(TemplateBuffer); loop++)
                {
                fprintf(handle, ",\n\n");
                Set_Deferred_Data_Offsets(current_icon_data+16, current_icon_data+20, IndiectedIconsBuffer, deferred_data_offset);
                Output_Data(handle, current_icon_data, 32);
                current_icon_data += 32;
                }
           
            /******************************************************************************************************/
            /***      Write out any deferred data which may be needed                                           ***/
            /******************************************************************************************************/           
            if (defered_data_size > 0)
                {
                fprintf(handle, ",\n\n");
                Output_Data(handle, IndiectedIconsBuffer, defered_data_size);
                }

            fprintf(handle, "\n       };\n\n\n\n\n");  
            fclose(handle);
            return(TRUE);
            }
        else
            {
            printf("Can not create WinDef file.\n\n\n");
            exit(0);
            }
        }

    return(FALSE);
    }
























/******************************************************************************/
/***                                                                        ***/
/***  CreateNewFile()                                                       ***/
/***                                                                        ***/
/***  Will create a text file for writing the 'C' structures into.          ***/
/***  This routine also puts some header information at the start of the    ***/
/***  file.                                                                 ***/
/***                                                                        ***/
/******************************************************************************/

void CreateNewFile(char *filename)
    {
    FILE *handle;

    if ((handle = fopen(filename, "w")) != NULL)
        {
        fprintf(handle, "/*\n    This file contains the ""Box"" window definitions as defined\n");
        fprintf(handle, "    in the template file ""%s"".\n*/\n\n\n\n", template_filename);

        fprintf(handle, "typedef struct\n");
        fprintf(handle, "        {\n");
        fprintf(handle, "        int     data[22];\n");
        fprintf(handle, "        } WINDOW;\n\n\n");


        fprintf(handle, "typedef struct\n");
        fprintf(handle, "        {\n");
        fprintf(handle, "        int     data[8];\n");
        fprintf(handle, "        } ICON;\n");

        fprintf(handle, "\n\n\n\n");
        fclose(handle);
        }
    }






/******************************************************************************/
/***                                                                        ***/
/***  Open_TemplateFile()                                                   ***/
/***                                                                        ***/
/***  Will attempt to open the template file.                               ***/
/***                                                                        ***/
/******************************************************************************/

int Open_TemplateFile(char *filename)
    {
    _kernel_swi_regs inregs, outregs;


    inregs.r[1] = (int) filename;

    if (_kernel_swi(Wimp_OpenTemplate, &inregs, &outregs) == NULL)
        {
        return(TRUE);
        }   
    else return(FALSE);
    }






/******************************************************************************/
/***                                                                        ***/
/***  Close_TemplateFile()                                                  ***/
/***                                                                        ***/
/***  Will attempt to close the template file.                              ***/
/***                                                                        ***/
/******************************************************************************/

void Close_TemplateFile()
    {
    _kernel_swi_regs inregs, outregs;

    _kernel_swi(Wimp_CloseTemplate, &inregs, &outregs);
    }







/******************************************************************************/
/***                                                                        ***/
/***  LoadNextWindowDefinition()                                            ***/
/***                                                                        ***/
/***  Will attempt to close the template file.                              ***/
/***                                                                        ***/
/******************************************************************************/

int LoadNextWindowDefinition(char *T_Buffer, char *I_Buffer, int buff_size, int *pos, int current_win)
    {
    _kernel_swi_regs inregs, outregs;
    char wildcard [12];


    strcpy(wildcard, "box?");
    wildcard[3] = (char) (current_win + '0');

    inregs.r[1] = (int) T_Buffer;
    inregs.r[2] = (int) I_Buffer;
    inregs.r[3] = (int) (I_Buffer + buff_size);
    inregs.r[4] = -1;
    inregs.r[5] = (int) wildcard;
    inregs.r[6] = 0;
    if (_kernel_swi(Wimp_LoadTemplate, &inregs, &outregs) == NULL)
        {
        *pos = outregs.r[6];
        }
    else
        {
        *pos = 0;
        }

    return((int) ((char *) outregs.r[2] - I_Buffer));
    }






/******************************************************************************/
/***                                                                        ***/
/***  get_number_of_icons()                                                 ***/
/***                                                                        ***/
/***  Will return the number of icons, the window definition holds.         ***/
/***                                                                        ***/
/******************************************************************************/

int get_number_of_icons(char *TemplateBuffer)
    {
    return((int) *(TemplateBuffer + 84));
    }







/******************************************************************************/
/***                                                                        ***/
/***  Output_Data()                                                         ***/
/***                                                                        ***/
/***  Writes out the data held at "buffer" into 'C' ASCII text format.      ***/
/***                                                                        ***/
/***  The routine will do 1 word at a time, in the format "0x%8X,", each    ***/
/***  line will contain 6 words. Each new line will contain 8 spaces. The   ***/
/***  final line will not have a comma or CR. The data is rounded up to     ***/
/***  nearest word.                                                         ***/
/***                                                                        ***/
/******************************************************************************/


void Output_Data(FILE *handle, char *Buffer, int bytes)
    {
    int count, offset;


    offset = 0;
    bytes = (bytes + 3)/4;                             /* round up to nearest word */

    while(bytes > 0)
        {
        count = 0;
        fprintf(handle, "        ");
        while((bytes > 0) && (count++ < 6))
            {
            print_hex(handle, *(int *)(Buffer+offset));
            bytes--;
            offset +=4;
            if (bytes != 0) fprintf(handle, ", ");       
            }
        if (bytes != 0) fprintf(handle, "\n");
        }
    }





/******************************************************************************/
/***                                                                        ***/
/***  print_hex()                                                           ***/
/***                                                                        ***/
/***  Will print a hexidecimal number, including leading zeros.             ***/
/***                                                                        ***/
/******************************************************************************/

void print_hex(FILE *handle, int value)
    {
    int loop, v;

    fprintf(handle, "0x");
    for(loop = 0; loop <=7; loop++)
        {
        v = (value & 0xF0000000) >> 28;
        if (v > 9) fprintf(handle, "%c", v+'A'-10);
            else fprintf(handle, "%c", v+'0');
        value = value << 4;
        }
    }







/******************************************************************************/
/***                                                                        ***/
/***  Set_Deferred_Data_Offsets()                                           ***/
/***                                                                        ***/
/***  Checks the flags to see if any data is pointing to the deferred data  ***/
/***  area, if it is the pointer is changed to an offset within the the     ***/
/***  window structure being created. Therefore once the structure is       ***/
/***  complted the offset can be converted back into an exact pointer again ***/
/***                                                                        ***/
/******************************************************************************/

void Set_Deferred_Data_Offsets(char *flag_data, char *data, char *deferred_data, int new_offset)
    {

    switch((*(int *)flag_data) & 0x103)
        {
        case 0x101:
        case 0x103:
            *(int *) (data + 0) = (int) ((char *)(*(int *) (data + 0))  - deferred_data + new_offset);
            if ((*(int *) (data + 4)) != 0xFFFFFFFF)
                *(int *) (data + 4) = (int) ((char *)(*(int *) (data + 4))  - deferred_data + new_offset);
            break;

        case 0x102:
            *(int *) (data + 0) = (int) ((char *)(*(int *) (data + 0))  - deferred_data + new_offset);
            break;

        default:
            break;
        }
    }


