/*----------------------------------------------------------*/
/*                                                          */
/*   PowerPPL                                               */
/*   Copyright (c) 1994 by Francis Gastellu                 */
/*                                                          */
/*----------------------------------------------------------*/

#define Uses_TRect
#define Uses_TEvent
#define Uses_TKeys
#define Uses_TDrawBuffer
#define Uses_TStreamableClass
#define Uses_TStreamable
#define Uses_TView
#define Uses_TWindow
#include <tv.h>
__link( RView )
__link( RWindow )

#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <strstrea.h>
#include <iomanip.h>

#include "colortbl.h"


//
// TTable functions
//

const char * const TColorTable::name = "TColorTable";


void TColorTable::write( opstream& os )
{
    TView::write( os );
}


void *TColorTable::read( ipstream& is )
{
    TView::read( is );
    return this;
}


TStreamable *TColorTable::build()
{
    return new TColorTable( streamableInit );
}


TStreamableClass RColorTable( TColorTable::name,
			 TColorTable::build,
			 __DELTA(TColorTable)
		       );


TColorTable::TColorTable(TRect& r) :
 TView( r )
{
}


void TColorTable::draw()
{
    TDrawBuffer buf;
    char        color = getColor(6);

    for(int y = 0; y <= size.y-1; y++)
	{
	buf.moveChar(0, ' ', color, size.x);
	for(int x = 0; x <= size.x-1; x++)
	    buf.moveChar(x, 32*y+x, color, 1);
	writeLine(0, y, size.x, 1, buf);
	}
    showCursor();
}

//
// cmCharFocused is a offset value (basically the ascii code of the
// current selected character) thus should be added, not or'ed, to
// cmAsciiTableCmdBase.
//

void TColorTable::charFocused()
{
    message(owner, evBroadcast, cmAsciiTableCmdBase + cmCharFocused,
      (void *) (cursor.x + 32 * cursor.y));
}


void TColorTable::handleEvent(TEvent& event)
{
    TView::handleEvent(event);

    if (event.what == evMouseDown)
	{
	do
	    {
	    if(mouseInView(event.mouse.where))
		{
		TPoint spot = makeLocal(event.mouse.where);
		setCursor(spot.x, spot.y);
		charFocused();
		}
	    } while (mouseEvent(event, evMouseMove));
	clearEvent(event);
	}
    else
	{
	if (event.what == evKeyboard)
	    {
	    switch (event.keyDown.keyCode)
		{
		case kbHome:
		    setCursor(0,0);
		    break;
		case kbEnd:
		    setCursor(size.x-1, size.y-1);
		    break;
		case kbUp:
		    if (cursor.y > 0)
			setCursor(cursor.x, cursor.y-1);
		    break;
		case kbDown:
		    if (cursor.y < size.y-1)
			setCursor(cursor.x, cursor.y+1);
		    break;
		case kbLeft:
		    if (cursor.x > 0)
			setCursor(cursor.x-1, cursor.y);
		    break;
		case kbRight:
		    if (cursor.x < size.x-1)
			setCursor(cursor.x+1, cursor.y);
		    break;
		case kbIns:
			event.what = evBroadcast;
			event.message.infoInt = (cursor.x + 32 * cursor.y);
			event.message.command = 1534;
			putEvent(event);
			break;
		default:
		    setCursor(event.keyDown.charScan.charCode % 32,
		      event.keyDown.charScan.charCode / 32);
		    break;
		}
	    charFocused();
	    clearEvent(event);
	    }
	}
}


//
// TReport functions
//

const char * const TColorReport::name = "TColorReport";


void TColorReport::write( opstream& os )
{
    TView::write( os );
    os << colorCode;
}


void *TColorReport::read( ipstream& is )
{
    TView::read( is );
    is >> colorCode;
    return this;
}


TStreamable *TColorReport::build()
{
    return new TColorReport( streamableInit );
}


TStreamableClass RColorReport( TColorReport::name,
			  TColorReport::build,
			  __DELTA(TColorReport)
			);


TColorReport::TColorReport(TRect& r) :
 TView(r)
{
    colorCode = 0;
}


void TColorReport::draw()
{
    TDrawBuffer buf;
    char        color = getColor(6);
    char        str[80];
    ostrstream  statusStr( str, sizeof str );

    statusStr
      << "  Char: " << ((colorCode == 0) ? (char) 0x20 : (char) colorCode)
      << " Decimal: " << setw(3) << (int) colorCode
      << " Hex " << hex << setiosflags(ios::uppercase)
      << setw(2) << (int) colorCode << "     " << ends;

    buf.moveStr(0, str, color);
    writeLine(0, 0, 32, 1, buf);
}


void TColorReport::handleEvent(TEvent& event)
{
    TView::handleEvent(event);
    if (event.what == evBroadcast)
	{
	if (event.message.command == cmAsciiTableCmdBase + cmCharFocused)
	    {
	    colorCode = event.message.infoLong;
	    drawView();
	    }
	}
}


//
// TColorChart functions
//

const char * const TColorChart::name = "TColorChart";


void TColorChart::write( opstream& os )
{
    TWindow::write( os );
}


void *TColorChart::read( ipstream& is )
{
    TWindow::read( is );
    return this;
}


TStreamable *TColorChart::build()
{
    return new TColorChart( streamableInit );
}


TStreamableClass RColorChart( TColorChart::name,
			      TColorChart::build,
			      __DELTA(TColorChart)
			    );


TColorChart::TColorChart() :
    TWindow(TRect(0, 0, 34, 12), "COLOR Chart", wnNoNumber),
    TWindowInit( &TColorChart::initFrame )
{
    TView *control;

    flags &= ~(wfGrow | wfZoom);
    palette = wpCyanWindow;

    TRect r = getExtent();
    r.grow(-1, -1);
    r.a.y = r.b.y - 1;
    control = new TReport( r );
    control->options |= ofFramed;
    control->eventMask |= evBroadcast;
    insert(control);

    r = getExtent();
    r.grow(-1, -1);
    r.b.y = r.b.y - 2;
    control = new TTable( r );
    control->options |= ofFramed;
    control->blockCursor();
    insert(control);

    control->select();
}
