static char *sccs_id= (sccs_id, "@(#)DrawController.c	3.10 7/28/92");

//$DrawController$
#include "Class.h"
#include "ET++.h"

#include "MenuBar.h"
#include "DrawController.h"
#include "Commands.h"
#include "TextShape.h"
#include "ImageShape.h"
#include "PictureShape.h"
#include "Picture.h"
#include "TextCmd.h"
#include "MenuItems.h"
#include "ObjList.h"
#include "DrawView.h"
#include "ObjInt.h"
#include "Alert.h"
#include "ImageItem.h"

#include "QuelInfo.h"
#include "Quel.h"
#include "Query.h"

short IZFLogo[]= {
#   include  "images/IZFLogo.im"
};


const int MaxColInk= 64;

Ink *InkPalette[256];

int NrInks()
{
  return MaxColInk;
};

int MaxInks()
{
  return MaxColInk + 64;
}

class Ink *GetInk(int i)
{
  return (i >= MaxInks() || i < 0) ? ePatBlack: InkPalette[i];
};

class Ink *GetHlInk()
{
  return InkPalette[MaxColInk-1];
};


MetaImpl(DrawController, (TP(drawView), 0));

DrawController::DrawController(DrawView *dv)
{
    drawView= dv;
}


void LoadGeoColors()
{
    extern char		*GEOCOLORS;
    char		*geo_color_rel= GEOCOLORS ? GEOCOLORS: "geo_colors";
    int			i;
    
    for (i= 0; i < MaxInks(); i++)
	  InkPalette[i]= ePatBlack;
    i= 0;
    InkPalette[i++]= ePatNone;
	
    if (GetInfo()->TableExists(geo_color_rel)) {
	 SetDb(GetGeoDB());
         QueryIter	qi(geo_color_rel, 0, 0,
				"colind", "red", "green", "blue", 0);
         char		**a;
         
         while (a= qi.Next()) {
           int ind= a[0] ? atoi(a[0]): 0;
           if (ind < 0 || ind >= MaxInks()) {
             fprintf(stderr, "Illegal color index: %d skipped\n", ind);
             continue;
           }
           InkPalette[ind]= a[1] && a[2] && a[3] ?
	     new RGBColor(atoi(a[1]), atoi(a[2]), atoi(a[3])) :
	     ePatBlack;
         }
    } else {
        ShowAlert(eAlertNote,
          "Color RGB values relation `@B%s@P'\ndoes not exist: Using default colors.",
          geo_color_rel);

	InkPalette[i++]= ePatWhite;
	InkPalette[i++]= ePatBlack;

	const int NCOLOR= 8;
        static unsigned char gRed_table[NCOLOR]= {255,255,255,0,0,255,0,0};
        static unsigned char gGreen_table[NCOLOR]= {255,255,0,255,0,180,180,0};
        static unsigned char gBlue_table[NCOLOR]= {255,0,0,0,255,0,70,0};

	for (int cnt= 1; cnt < NCOLOR; cnt++)
	  InkPalette[i++]= new RGBColor(gRed_table[cnt], gGreen_table[cnt], gBlue_table[cnt]);
    }
}
    
#ifdef ET25
#else
class MenuBar *DrawController::CreateMenuBar(EvtHandler *next)
{
    PullDownMenu	*m;
    int			i= 0, font, size= gSysFont->Size();
    GrFont		fid= (GrFont)gSysFont->Fid();
    char		*fontname;
    Point		tb(4,0);  // border around textitems
    ObjList		*list= new ObjList;

    LoadGeoColors();

    //---- sun menu
    m= new PullDownMenu(new ImageItem(IZFLogo, Point(24)));
    m->AppendItems("About GEO", cABOUT, 0);
    list->Add(new PullDownItem(m));
    
    //---- font menu
    m= new PullDownMenu("Fonts", TRUE);
    for (font= 0; fontname= gFontManager->IdToName((GrFont)font); font++)
	m->Append(new TextItem(cFIRSTFONT+font, fontname, gSysFont, tb)); 
    list->Add(new PullDownItem(m));
	
    //---- styles menu
    m= new PullDownMenu("Styles");
    m->Append(new TextItem(cFIRSTFACE+eFacePlain, "Plain", 
				    new_Font(fid, size, eFacePlain), tb));
    m->Append(new TextItem(cFIRSTFACE+eFaceBold, "Bold", 
				    new_Font(fid, size, eFaceBold), tb));
    m->Append(new TextItem(cFIRSTFACE+eFaceItalic, "Italic", 
				    new_Font(fid, size, eFaceItalic), tb));
    m->Append(new TextItem(cFIRSTFACE+eFaceUnderline, "Underline", 
				    new_Font(fid, size, eFaceUnderline), tb));
    m->Append(new TextItem(cFIRSTFACE+eFaceOutline, "Outline", 
				    new_Font(fid, size, eFaceOutline), tb));
    m->Append(new TextItem(cFIRSTFACE+eFaceShadow, "Shadow", 
				    new_Font(fid, size, eFaceShadow), tb));
    list->Add(new PullDownItem(m));
    
    //---- sizes menu
    m= new PullDownMenu("Sizes");
    for (int sz= 9; sz <= 24; sz++)
	m->Append(new TextItem(cFIRSTSIZE+sz, form("%d  ", sz), gSysFont, tb)); 
    list->Add(new PullDownItem(m));

    //---- format menu
    m= new PullDownMenu("Format");
    m->AppendItems("Align Left",     cFIRSTADJUST,
		   "Align Right",    cFIRSTADJUST + 1,
		   "Align Center",   cFIRSTADJUST + 2,
		   "Justify",        cFIRSTADJUST + 3,
		   "-",
		   "Single Spacing", cFIRSTSPACING + eOne,
		   "1-1/2 Spacing",  cFIRSTSPACING + eOneHalf,
		   "Double Spacing", cFIRSTSPACING + eTwo,
		   0);
    list->Add(new PullDownItem(m));
    
    //---- ink menu
    m= new PullDownMenu("Ink", FALSE, 10, 0);
    m->AppendItem("None", cFIRSTPAT);
    for (i= 1; InkPalette[i]; i++)
	m->Append(new PatternItem(cFIRSTPAT+i, InkPalette[i]));
    list->Add(new PullDownItem(m));
    m->SetFlag(eMenuNoScroll);
    
    //---- line menu
    m= new PullDownMenu("Lines");
    for (int cap= 0; cap < 4; cap++)
	m->Append(new LineStyleItem(cFIRSTPEN+cap, 1, (GrLineCap)cap));
    m->AppendItems("-", "Hairline",  cFIRSTPENSIZE, 0);
    for (int lw= 1; lw <= 30; lw++)
	m->Append(new LineStyleItem(cFIRSTPENSIZE+lw, lw));
    list->Add(new PullDownItem(m));
    
    //---- pen ink menu
    m= new PullDownMenu("Pen Ink", FALSE, 10, 0);
    m->AppendItem("None", cFIRSTPPAT);
    for (i= 1; InkPalette[i]; i++)
	m->Append(new PatternItem(cFIRSTPPAT+i, InkPalette[i]));
    list->Add(new PullDownItem(m));
    m->SetFlag(eMenuNoScroll);

    return new MenuBar(next, list);
}
#endif

Command *DrawController::DoMenuCommand(int cmd)
{
    TextShape *activeText= drawView->GetActiveText();
    TextView *tv= 0;

    if (activeText)
	tv= activeText->GetTextView();
	
    if (drawView->Selected() <= 0)
	return 0;
	
    if (cmd >= cFIRSTPAT && cmd <= cLASTPAT)
	return new SimplePropertyCommand(drawView, eShapePattern, cmd-cFIRSTPAT, "set ink");

#ifdef ET25
#else
    if (cmd >= cFIRSTPPAT && cmd <= cLASTPPAT) {
	if (tv)
	    return new ChangeStyleCommand(tv, cmd, "set penink", eStInk, 
				StyleSpec(eFontDefault,eFacePlain,0,InkPalette[cmd-cFIRSTPPAT]));
	return new SimplePropertyCommand(drawView, eShapePenPattern, cmd-cFIRSTPPAT, "set penink");
    }
#endif

    if (cmd >= cFIRSTPEN && cmd <= cLASTPEN)
	return new SimplePropertyCommand(drawView, eShapeArrows, cmd-cFIRSTPEN, "set arrows");

    if (cmd >= cFIRSTPENSIZE && cmd <= cLASTPENSIZE)
	return new SimplePropertyCommand(drawView, eShapePensize, cmd-cFIRSTPENSIZE, "set pensize");

#ifdef ET25
#else
    if (cmd >= cFIRSTSIZE && cmd <= cLASTSIZE) {
	if (tv)
	    return new ChangeStyleCommand(tv,cmd,"set size", eStSize, 
				StyleSpec(eFontDefault,eFacePlain,cmd-cFIRSTSIZE));
	return new PropertyCommand(drawView, eShapeTextSize , new ObjInt(cmd-cFIRSTSIZE), "set size");
    }

    if (cmd >= cFIRSTFONT && cmd <= cLASTFONT) {
	if (tv)
	    return new ChangeStyleCommand(tv,cmd,"set font", eStFont, 
				StyleSpec(GrFont(cmd-cFIRSTFONT),eFacePlain,0));
	return new PropertyCommand(drawView, eShapeTextFont, new ObjInt(cmd-cFIRSTFONT), "set font");
    }

    if (cmd >= cFIRSTFACE && cmd <= cLASTFACE) {
	if (tv)
	    return new ChangeStyleCommand(tv,cmd,"set face", eStFace, 
				StyleSpec(eFontDefault,GrFace(cmd-cFIRSTFACE),0));
	return new PropertyCommand(drawView, eShapeTextFace, new ObjInt(cmd-cFIRSTFACE), "set face");
    }
#endif

    if (cmd >= cFIRSTADJUST && cmd <= cLASTADJUST)
	return new SimplePropertyCommand(drawView, eShapeAdjust, cmd-cFIRSTADJUST, "set just");

    if (cmd >= cFIRSTSPACING && cmd <= cLASTSPACING)
	return new SimplePropertyCommand(drawView, eShapeSpacing, cmd-cFIRSTSPACING, "set spacing");
    return 0;
}

#ifdef ET25
#else
Command *DrawController::DoImport(istream &s, FileType *ft)
{
    Shape *ns= 0;
#ifdef ET23
    Symbol t= ft->Type();
#else
#endif
	
#ifdef ET23
    if (t == cDocTypeAscii) {
#else
    if (strcmp(ft->Type(), cDocTypeAscii) == 0) {
#endif
	GapText t;
	t.ReadFromAsPureText(s, ft->SizeHint());
	TextShape *ts;
	if (ts= drawView->GetActiveText()) {
	    Command *cmd= ts->GetTextView()->InsertText(&t);
	    ts->Invalidate();
	    return cmd;
	}
	
	ts= new TextShape;
	ts->Init(drawView->LastClick(), drawView->LastClick()+10);
	ts->GetTextView()->InsertText(&t);
	ns= ts;
	
#ifdef ET23
    } else if (t == cDocTypeSunRaster || t == cDocTypeSunBitmap
			|| t == cDocTypeX11Bitmap) {
#else
    } else if (strcmp(ft->Type(), cDocSunRasterFile) == 0
	|| strcmp(ft->Type(), cDocSunRasterFileAscii) == 0) {
#endif
	char *name= ft->PathName();
	if (name == 0)
	    return gNoChanges;
	Bitmap *bm= new Bitmap(name);
	if (bm)
	    ns= new ImageShape(bm);
#ifdef ET23
    } else if (t == cDocTypeETPict || t == cDocTypeEpsf) {
	char *name= ft->PathName();
        if (name == 0)
            return gNoChanges;
        Picture *pic= new Picture(name);
        if (pic)
            ns= new PictureShape(pic);
#endif
    }
    if (ns)
	return new SPasteCommand(drawView, ns, drawView->LastClick());
    return gNoChanges;
}
#endif
