/*************************************************************************
**
** Project:     ShowFont
** Version:     1.1         $VER: ShowFont 1.2 (rev.1.011) source
** Author:      Dariusz J. Garbowski - Thufor/BlahBlah
** Start Date:  1997.02.0x  - OpenFont
** End Date:    1997.05.04  - rev.1.011
**
** About:   It opens and shows selected font.
**          ?
** Thx:     to Warhawk/CCP for help in OpenFont version
**          to all members of BlahBlah
**          to
**          to 
**
*************************************************************************/

#include <intuition/intuition.h>
#include <exec/memory.h>

#include <proto/dos.h>
#include <proto/diskfont.h>
#include <proto/graphics.h>
#include <proto/exec.h>
#include <proto/intuition.h>

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

#include "stdlibext.h"

#define PRG_NAME "ShowFont 1.2"
#define REVISION "1.011"
#define OS_VERSION 39
#define MAX_FONTNAME_WIN_TITLE 30   /* max length of fontname showed on window title bar */

const char VERSION[] = "$VER: " PRG_NAME " ("  __DATE__  ") Revision: " REVISION;
UBYTE *mainwtitle;
UBYTE mainwndtitle[40+MAX_FONTNAME_WIN_TITLE+8] = PRG_NAME;        /* main window title string */
UBYTE screentitle[] = PRG_NAME " ©1997 by Dariusz J. 'Thufor' Garbowski, BlahBlah Product";     /* screen title string */
UBYTE temp_var[100] = "/0";                 /* temporary variable ###size 100? */

/* prototypes */
int prep_window(LONG *argv, UBYTE *lines[], int nr_lines );
int my_sprintf( char *ctl, ... );
int show_font(long argv[]);
BOOL SaveRastPortDT(struct Screen *scr, struct RastPort *rp, LONG  xxx, LONG yyy, LONG xsize, LONG ysize, UBYTE *FileName);

struct TextFont *t_font;
struct TextAttr t_attr =
{NULL, NULL, NULL, FPF_DISKFONT};

#define CLI_PARAM_FONTNAME 0
#define CLI_PARAM_FONTSIZE 1
#define CLI_PARAM_DELAY 2
#define CLI_PARAM_TEXT 3
#define CLI_PARAM_SAVE 4
#define CLI_PARAM_XWIN 5
#define CLI_PARAM_YWIN 6
#define CLI_PARAM_PUBSCREEN 7
#define CLI_PARAM_END 8
UBYTE * cli_template = "FONTNAME/A,FONTSIZE/A/N,DL=DELAY/N,TXT=TEXT/K,SV=SAVE/K,XW=XWIN/N/K,YW=YWIN/N/K,PUBSCR=PUBSCREEN/K";
LONG argv[CLI_PARAM_END] = { 0, 0, 0, 0, 0, 0, 0, 0 };
struct RDArgs * rdargs = NULL;

struct Library *DiskfontBase;
struct GfxBase *GfxBase;
struct IntuitionBase *IntuitionBase;

#define MY_MAIN_WIN_TAGS_LEFT 0
#define MY_MAIN_WIN_TAGS_TOP 1
#define MY_MAIN_WIN_TAGS_WIDTH 2
#define MY_MAIN_WIN_TAGS_HEIGHT 3
#define MY_MAIN_WIN_TAGS_CLOSEGADGET 6
#define MY_MAIN_WIN_TAGS_SCREENTITLE 8
#define MY_MAIN_WIN_TAGS_TITLE 9
#define MY_MAIN_WIN_TAGS_PUBSCREEN 10

struct TagItem main_win_tags[] =
{
    {WA_Left,       0L},
    {WA_Top,        0L},
    {WA_Width,      320L},
    {WA_Height,     100L},
    {WA_DragBar,    1L},
    {WA_DepthGadget,    1L},
    {WA_CloseGadget,    1L},
    {WA_NewLookMenus,   1L},
    {WA_ScreenTitle,    (ULONG)screentitle},
    {WA_Title,  (ULONG)mainwndtitle},
    {WA_PubScreen,  0L},
    {WA_IDCMP,  IDCMP_CLOSEWINDOW},
    {0, 0}
};

struct Window *main_window;
struct Screen *pub_screen;

int main(void)
{
    int error = 0;      /* returned to dos... */

    if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", OS_VERSION))
    {
        if (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", OS_VERSION))
        {
            if (DiskfontBase = OpenLibrary("diskfont.library", OS_VERSION))
            {
                if ((rdargs = ReadArgs(cli_template, argv, NULL)) != NULL)
                {
                    error = show_font(argv);
                    FreeArgs(rdargs);
                }
                else
                {
                    PrintFault( IoErr(), PRG_NAME );
                }
                CloseLibrary(DiskfontBase);
            }
            CloseLibrary((struct Library *)GfxBase);
        }
        CloseLibrary((struct Library *)IntuitionBase);
    }
    else
        error = RETURN_FAIL;     /* can't open something, etc. */

    return error;
}

/*
** Show font in a window
*/
int show_font(long *argv)
{
    int error = 0;      /* returned to main()... */
    long i = 0;
    int x, y;

    int nr_lines = 6;      /* liczba linii tekstu */
    UBYTE *lines[] =
    {
        (UBYTE *)" !\"#$%&\'()*+,-./0123456789:;<=>?",
        (UBYTE *)"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_",
        (UBYTE *)"`abcdefghijklmnopqrstuvwxyz{|}~\x7f",
        (UBYTE *)" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿",
        (UBYTE *)"ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß",
        (UBYTE *)"aaâãäåæçeeêëiiîïðñooôõö÷øuuûüyþÿ",
        NULL
    };

    if ((UWORD)*((long *)argv[CLI_PARAM_FONTSIZE]) > 255)
    {
        /* Printf( "Font size could be max. 255!\n" ); */
        PrintFault( ERROR_BAD_NUMBER, PRG_NAME );
        return RETURN_ERROR;
    }

    t_attr.ta_Name = (UBYTE *)argv[CLI_PARAM_FONTNAME];
    t_attr.ta_YSize = (UWORD)*((long *)argv[CLI_PARAM_FONTSIZE]);

    /* parsing cli param TEXT */
    if ((UBYTE *)argv[CLI_PARAM_TEXT])
    {
        nr_lines = 1;
        lines[0] = (UBYTE *)argv[CLI_PARAM_TEXT];
    }

    if (t_font = OpenDiskFont(&t_attr))
    {
        if (pub_screen = LockPubScreen( (UBYTE *)argv[CLI_PARAM_PUBSCREEN] ))
        {
            prep_window( argv, lines, nr_lines );
            main_window = OpenWindowTagList( NULL, main_win_tags );
            UnlockPubScreen( NULL, pub_screen );
            SetAPen( main_window->RPort, 1 );
            SetFont( main_window->RPort, t_font );

            /* showing text in window */
            for (i = 0; i < nr_lines; i++)
            {
                x = 1+main_window->BorderLeft;
                y = i*(t_attr.ta_YSize+(unsigned long)(t_attr.ta_YSize/10)+1)+main_window->RPort->TxBaseline+main_window->BorderTop+1;
                Move( main_window->RPort, x, y );
                Text( main_window->RPort, lines[i], strlen( lines[i] ) );
            };
            RefreshWindowFrame( main_window );  /* for a reason of too small window/screen */

            /* closing window */
            if (argv[CLI_PARAM_DELAY]==0)
            {
                WaitPort( main_window->UserPort );
                ReplyMsg( GetMsg( main_window->UserPort ) );
            }
            else
            {
                Delay(*(ULONG *)argv[CLI_PARAM_DELAY]);
            }

/* WHY IT RETURNS SCREEN'S SIZE?!!!
            x = GetBitMapAttr( main_window->RPort->BitMap, BMA_WIDTH);
            y = GetBitMapAttr( main_window->BorderRPort->BitMap, BMA_HEIGHT);
            SaveRastPortDT( pub_screen, NULL, 0, 0, x, y, "ram:plik.iff" );
*/
/*            x = main_window->Width;
            y = main_window->Height;
*/
            /* Save font to iff file */
            if( (UBYTE *)argv[CLI_PARAM_SAVE] != NULL ){

                struct RastPort *rpa;

                if( rpa = (struct RastPort *)AllocVec( sizeof( struct RastPort ), MEMF_ANY ) ){
                    struct BitMap *bmpa;

                    if( bmpa = AllocBitMap( x, y, GetBitMapAttr( &pub_screen->BitMap, BMA_DEPTH ), BMF_CLEAR, main_window->RPort->BitMap) ){
                        ULONG xa, ya;


                        xa = main_window->Width - main_window->BorderLeft - main_window->BorderRight;
                        ya = main_window->Height - main_window->BorderTop - main_window->BorderBottom;
                        SaveRastPortDT( pub_screen, main_window->RPort,
                                        main_window->BorderLeft, main_window->BorderTop,
                                        xa, ya, (UBYTE *)argv[CLI_PARAM_SAVE] );
                        FreeBitMap( bmpa );
                    }
                    FreeVec( rpa );
                }
            }

            CloseWindow(main_window);

        };
        CloseFont(t_font);
    }
    else
    {
        Printf("Couldn't open '%s'.\n",(UBYTE *)argv[CLI_PARAM_FONTNAME]);
        error = RETURN_ERROR;
    };

    return error;
}

/*
** Prints text in RastPort from table of pointers to text lines.
** Last pointer should be NULL (it's the end of text).
*/
LONG TextRastPort( struct RastPort *rport,  UBYTE *lines[] )
{
#########################
}

/*
** prep_window() prepares window (using params from Shell)
*/
int prep_window( LONG *argv, UBYTE *lines[], int nr_lines )
{
        LONG i;
        int x, y;
        struct RastPort *vrport;
        struct TextExtent t_extent;

        /* preparing window tags, etc. */
        mainwtitle = strcat(mainwndtitle, " : ");
        i = strlen( (UBYTE *)argv[CLI_PARAM_FONTNAME] );
        mainwtitle = strcat( mainwndtitle, (UBYTE *)(i = argv[CLI_PARAM_FONTNAME]+((i-MAX_FONTNAME_WIN_TITLE > 0) ? i-MAX_FONTNAME_WIN_TITLE : 0 )) );
        /* preparing main window title */
        my_sprintf( "%ld", temp_var, *(long *)argv[CLI_PARAM_FONTSIZE] );
        i = strlen( mainwndtitle );
        mainwndtitle[i] = ' ';
        mainwndtitle[i+1] = '\0';
        mainwtitle = strcat( mainwndtitle, temp_var );
        main_win_tags[MY_MAIN_WIN_TAGS_TITLE].ti_Data = (ULONG)mainwtitle;
        /* if cli param DELAY > 1 then no CLOSEGADGET */
        if (argv[CLI_PARAM_DELAY])
            if ( *(ULONG *)argv[CLI_PARAM_DELAY] < 0)
                main_win_tags[MY_MAIN_WIN_TAGS_CLOSEGADGET].ti_Data = (ULONG)TRUE;
            else
                main_win_tags[MY_MAIN_WIN_TAGS_CLOSEGADGET].ti_Data = (ULONG)FALSE;
        /* parsing cli param XWIN */
        if (argv[CLI_PARAM_XWIN])
            main_win_tags[MY_MAIN_WIN_TAGS_LEFT].ti_Data = *(ULONG *)argv[CLI_PARAM_XWIN];


            if (!(vrport = (struct RastPort *)AllocVec( sizeof( struct RastPort ), MEMF_ANY )) )
                return RETURN_ERROR;

            InitRastPort( vrport );         /* Initialize of virtual RastPort */
            SetFont( vrport, t_font );

            /* getting x size of window to fit text */
            x = 0;
            /* points-length of 'longest' line */
            for (i = 0; i < nr_lines; i++)
            {
                TextExtent( vrport, lines[i], strlen(lines[i]), &t_extent );
                if (x < t_extent.te_Extent.MaxX-t_extent.te_Extent.MinX+1+pub_screen->WBorLeft+pub_screen->WBorRight)
                    x = t_extent.te_Extent.MaxX-t_extent.te_Extent.MinX+1+pub_screen->WBorLeft+pub_screen->WBorRight;
            }
            FreeVec( vrport );

            /* preparing window tags, etc. */
            main_win_tags[MY_MAIN_WIN_TAGS_HEIGHT].ti_Data =
                    pub_screen->BarHeight+1+pub_screen->WBorBottom+1+nr_lines*(t_attr.ta_YSize+(unsigned long)(t_attr.ta_YSize/10)+1);
            /* setting x size of main window */
            if (x < pub_screen->Width)
                main_win_tags[MY_MAIN_WIN_TAGS_WIDTH].ti_Data = x;
            else
                main_win_tags[MY_MAIN_WIN_TAGS_WIDTH].ti_Data = pub_screen->Width;
            /* parsing cli param YWIN */
            if (argv[CLI_PARAM_YWIN])
                main_win_tags[MY_MAIN_WIN_TAGS_TOP].ti_Data = *(ULONG *)argv[CLI_PARAM_YWIN];
            else
                main_win_tags[MY_MAIN_WIN_TAGS_TOP].ti_Data = pub_screen->BarHeight+1;
            main_win_tags[MY_MAIN_WIN_TAGS_PUBSCREEN].ti_Data = (ULONG) pub_screen;

}

/*
** Second param is pointer to buffer[] where formatted string will be put.
*/
int my_sprintf( char *ctl, ... )
{
    long *arg1;
    APTR *buffer;

    arg1 = (long *)(&ctl + 2);
    buffer = (APTR *)(&ctl + 1);
    RawDoFmt( ctl, arg1, (void (*))"\x16\xc0\x4e\x75", *buffer );

    return 0;
}

/*
**
** $VER: SaveRastPortDT 1.00 (1997.04.27) rev.1.00
**
** Author of screen grabber (I don't know what's the name of the program, because
**  I have only small part of a source): Aris Basic (aris@pwe.augusta.de)
** Some changes (SaveDTScreen) made by:  Lukasz Prokulski (LeMUr/BlaBla)
** SaveRastPortDT changes:               Dariusz J. Garbowski (Thufor/BlahBlah)
**                                       (thufor@zeus.polsl.gliwice.pl)
**
** if xsize == -1 then xsize will be set to BitMap Width
** if ysize == -1 then ysize will be set to BitMap Height
**
*/

#include <datatypes/pictureclass.h>
#include <exec/memory.h>
#include <dos/dos.h>

#include <datatypes/datatypes.h>
#include <datatypes/datatypesclass.h>
#include <datatypes/pictureclass.h>

#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/datatypes.h>


extern struct ExecBase *SysBase;
extern struct IntuitionBase *IntuitionBase;
extern struct DosLibrary *DOSBase;
extern struct GfxBase *GfxBase;
extern struct Library *DataTypesBase;


BOOL SaveRastPortDT(struct Screen *scr, struct RastPort *rp, LONG  xxx, LONG yyy, LONG xsize, LONG ysize, UBYTE *FileName)
{
    BOOL retval = TRUE;
    BPTR FileHandle;

    struct RastPort *RPort;

    /* if there isn't selected BitMap then get Screen's BitMap */
    if( rp == NULL )
        rp = &(scr->RastPort);

    if(RPort = (struct RastPort *)AllocVec(sizeof(struct RastPort), MEMF_ANY))
    {
        struct BitMap *BitMap;
        LONG Left = xxx;                /* scr->LeftEdge;*/
        LONG Top = yyy;                 /* scr->TopEdge; */
        LONG Width = xsize;             /* scr->Width;   */
        LONG Height = ysize;            /* scr->Height;  */
        LONG PageWidth = Width;
        LONG PageHeight = Height;
        LONG Depth = GetBitMapAttr( rp->BitMap, BMA_DEPTH);

        if( Width == -1 )
            Width = GetBitMapAttr( rp->BitMap, BMA_WIDTH );

        if( Height == -1)
            Height = GetBitMapAttr( rp->BitMap, BMA_HEIGHT );

        InitRastPort(RPort);

        if(BitMap = AllocBitMap(Width, Height, Depth, BMF_CLEAR, rp->BitMap))
        {
            ULONG *ColourTable;
            ULONG ModeID = GetVPModeID(&scr->ViewPort);
            LONG NumColours = scr->ViewPort.ColorMap->Count;

            RPort->BitMap = BitMap;
            ClipBlit(   rp,                /* &scr->RastPort, */
                        Left, Top,
                        RPort,
                        0, 0,
                        Width, Height,
                        0xC0);
            WaitBlit();

            if(ColourTable = (ULONG *)AllocVec(sizeof(ULONG) * 3 * NumColours, MEMF_ANY))
            {
                Object *Picture;
                GetRGB32(scr->ViewPort.ColorMap, 0, NumColours, ColourTable);

                if(Picture = NewDTObject(NULL,
                                                    DTA_SourceType, DTST_RAM,
                                                    DTA_GroupID, GID_PICTURE,
                                                    PDTA_NumColors, NumColours,
                                                    PDTA_BitMap, BitMap,
                                                    PDTA_ModeID, ModeID,
                                                    TAG_DONE))
                {
                    struct ColorRegister *ColourMap;
                    struct BitMapHeader *BitMapHeader;
                    ULONG *Colours;

                    if(GetDTAttrs(Picture,
                                        PDTA_BitMapHeader, &BitMapHeader,
                                        PDTA_ColorRegisters, &ColourMap,
                                        PDTA_CRegs, &Colours,
                                        TAG_DONE) == 3)
                    {
                        BitMapHeader->bmh_Left = Left;
                        BitMapHeader->bmh_Top = Top;
                        BitMapHeader->bmh_Width = Width;
                        BitMapHeader->bmh_Height = Height;
                        BitMapHeader->bmh_Depth = Depth;
                        BitMapHeader->bmh_PageWidth = PageWidth;
                        BitMapHeader->bmh_PageHeight = PageHeight;

                        CopyMem(ColourTable, Colours, 3 * sizeof(ULONG) * NumColours);

                        while(NumColours--)
                        {
                            ColourMap->red = (UBYTE)((*Colours++) >> 24);
                            ColourMap->green = (UBYTE)((*Colours++) >> 24);
                            ColourMap->blue = (UBYTE)((*Colours++) >> 24);
                            ColourMap++;
                        }

                        if(FileHandle = Open(FileName, MODE_NEWFILE))
                        {
                            if(DoMethod(Picture, DTM_WRITE, NULL,
                                            FileHandle, DTWM_IFF, NULL))
                            {
                                Close(FileHandle);
                                retval = FALSE;
                            }
                            else
                            {
                                Close(FileHandle);
                                DeleteFile(FileName);
                            }
                        }
                    }
                    DisposeDTObject(Picture);
                    BitMap = NULL;
                }
                FreeVec(ColourTable);
            }
            FreeBitMap(BitMap);
        }
        FreeVec(RPort);
    }
    return retval;
}


