/*
 * This software is copyrighted as noted below.  It may be freely copied,
 * modified, and redistributed, provided that the copyright notice is
 * preserved on all copies.
 *
 * There is no warranty or other guarantee of fitness for this software,
 * it is provided solely "as is".  Bug reports or fixes may be sent
 * to the author, who may or may not act on them as he desires.
 *
 * You may not include this software in a program or other software product
 * without supplying the source, or without informing the end-user that the
 * source is available for no extra charge.
 *
 * If you modify this software, you should include a notice giving the
 * name of the person performing the modification, the date of modification,
 * and the reason for such modification.
 */
/*
 * pc.c - Show images on PCs using the GRX library.
 *
 * Author:      Raul Rivero
 *              Mathematics Dept.
 *              University of Oviedo
 * Date:        Mon Jan 4 1993
 * Copyright (c) 1993, Raul Rivero
 *
 */

#include <lug.h>
#include <lugfnts.h>


/*
 * Look here !!!
 * =============
 *
 * This code is valid only if we have defined the iPC
 * macro ( read the root Makefile for more information ).
 *
 */

#ifdef iPC

#include <grx.h>
#include <mousex.h>

show_bitmap( name, in, ditherflag )
char *name;
bitmap_hdr *in;
int ditherflag;
{
        bitmap_hdr out8;
        bitmap_hdr out24;
        bitmap_hdr *bitmap8 = in;
        bitmap_hdr *bitmap24 = in;
        register int i, r, g, b;
        register byte *ptr, *scr;
        register int y;
        int xinit, yinit;
        int xsize, ysize;
        double j;
        MouseEvent event;

        if ( in->magic != LUGUSED )
                error( 19 );

        /* We need get the graphics limits, so switch to graphics ... */
        GrSetMode( GR_default_graphics );
        xsize = GrSizeX();
        ysize = GrSizeY();
        /* ... and return to text mode */
        GrSetMode( GR_default_text );

        /*
         * Resample if the bitmap are greater than
         * the screen.
         */
        if ( in->xsize > xsize || in->ysize > ysize ) {
                double xfactor, yfactor;
                int newx, newy;

                /* Get the factor to adjust */  
                xfactor = ((double) xsize) / ((double) in->xsize);
                yfactor = ((double) ysize) / ((double) in->ysize);
                /* 
                 * Now, select the correct. What we need is the image
                 * inside the physical display borders, so we choose
                 * the factor which suports this.
                 */
                if ( yfactor*in->xsize > xsize ) {
                        newx = xfactor * in->xsize;
                        newy = xfactor * in->ysize;
                }else {
                        newx = yfactor * in->xsize;
                        newy = yfactor * in->ysize;
                }
                fprintf( stderr, "Resampling to screen ( %dx%d )\n",
                         xsize, ysize); 
                fprintf( stderr, "From %dx%d to %dx%d\n", in->xsize, in->ysize,
                         newx, newy );
                adjust_bitmap( in, &out24, newx, newy, 0 );
                bitmap24 = &out24;
        }

        /*
         * Ooppppsssss !!!, only 8 planes.
         */
        if ( bitmap24->depth > 8 ) {
                if ( ditherflag ) {
                        fprintf( stderr, "Dithering ...\n" );
                        dither_image( bitmap24, &out8, 6, (double) 1.0 );
                }else{
                        fprintf( stderr, "Quantizing ...\n" );
                        quantize( bitmap24, &out8, 256 );
                }
                bitmap8 = &out8;
        }else bitmap8 = bitmap24;

        /* If we are using a resample image, now we can free it */
        if ( bitmap24 == &out24 ) {
                freebitmap( &out24 );
        }

        /* Ok, all do it. Lets go to show the image !. */
        GrSetMode( GR_default_graphics );

        /*
         * Set a null color map.
         */
        for ( i = 0; i < 256 ; i++ ) {
                GrSetColor( i, 0, 0, 0 );
        }

        /*
         * Dump the image to screen ( centered ).
         */
        xinit = ( GrSizeX() >> 1 ) - ( bitmap8->xsize >> 1 );
        yinit = ( GrSizeY() >> 1 ) - ( bitmap8->ysize >> 1 );
        ptr = bitmap8->r;
        scr = (char *) 0xd0000000 + xinit + yinit * GrSizeX();
        for ( y = 0; y < bitmap8->ysize ; y++, scr += xsize,
                                         ptr += bitmap8->xsize ) {
                bcopy( ptr, scr, bitmap8->xsize );
        }

        /*
         * Fade in the image.
         */
        for ( j = 0.; j <= 1. ; j += 0.05 ) {
                for ( i = 0, ptr = bitmap8->cmap; i < bitmap8->colors ; i++ ) {
                        r = j * (double)*ptr++;
                        g = j * (double)*ptr++;
                        b = j * (double)*ptr++;
                        GrSetColor( i, r, g, b );
                }
        }

        if ( bitmap8 == &out8 )
                freebitmap( &out8 );

        /*
         * Now wait for a interaction ( from the user ) and exit.
         */
        if(MouseDetect()) {
                /*
                 * Ok, we can use the right button from the mouse
                 * or the ESC key ( from the keyboard, or has your
                 * mouse has a ESC key ? ).
                 */
                MouseEventMode(0);
                /*
                 * If you are a UNIX programmer you know the events,
                 * else what a pity !.
                 */
                for( ; ; ) {
                        MouseGetEvent( (M_KEYPRESS|M_POLL|M_RIGHT_UP|M_NOPAINT ),
                                        &event);
                        if( event.flags ) {
                                break;
                        }
                }
                MouseUnInit();
        }else { 
                /* 
                 * Oooopppss!, no mouse detected so only handle 
                 * the keyboard.
                 */
                getkey();
        }

        /*
         * Fade out the image.
         */
        for ( j = 1.; j >= 0. ; j -= 0.05 ) {
                for ( i = 0, ptr = bitmap8->cmap; i < bitmap8->colors ; i++ ) {
                        r = j * (double)*ptr++;
                        g = j * (double)*ptr++;
                        b = j * (double)*ptr++;
                        GrSetColor( i, r, g, b );
                }
        }

        /*
         * Return to the text mode.
         */
        GrSetMode( GR_default_text );

}


#endif  /* iPC */
