/*

  This is a part of the Project Frontier's Source code.

  Copyright (C) 1994-1998 Francis Gastellu
                      aka Lone Runner/Aegis

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#define Uses_MsgBox
#define Uses_TKeys
#define Uses_TScroller
#define Uses_TDrawBuffer
#define Uses_TRect
#define Uses_TProgram
#define Uses_TDeskTop
#define Uses_TStreamableClass
#define Uses_TListBox
#define Uses_TKeys
#define Uses_TWindow
#define Uses_TScrollBar
#include <tv.h>
__link(RScroller)
__link(RScrollBar)

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

#include <fstream.h>

#include "tvcmds.h"
#include "fileview.h"
#include "tagger.h"
#include <string.h>
#include <alloc.h>

#define cTaggerViewer "\x09\x09\x0A\x0B\x0C"

#pragma warn -ias
const char * const TTaggerWindow::name = "TTaggerWindow";
const char * const TTaggerList::name = "TTaggerList";
#pragma warn .ias

extern char errorMessage[128];
extern int lastfocused;
extern char errorFichier[128];
extern int errorLineNumber;
extern int inMacro;
extern int inMacro2;
extern TCollection *tagList;
extern int viewerType;
extern Boolean EGAmode;
int curTag;


TTaggerList::TTaggerList(TRect& bounds, TScrollBar *aVScrollBar) :
	TListBox( bounds , 1, aVScrollBar)
{
	growMode = gfGrowHiX | gfGrowHiY;
}

TPalette& TTaggerList::getPalette() const
{
	static TPalette palette( cTaggerViewer, sizeof(cTaggerViewer)-1 );
	return palette;
}

#pragma warn -par
void TTaggerList::write( opstream& os )
{
}

void *TTaggerList::read( ipstream& is )
{
return this;
}
#pragma warn .par


void TTaggerWindow::removeAll()
{
	 tagListBox->newList( 0 );
}

void TTaggerWindow::update()
{
	tagListBox->setRange( tagList->getCount() );
	tagListBox->drawView();
}

void TTaggerWindow::trackTag( int makeFocused )
{
char ligne[255];
char linenum[8] = "";
char x[2] = "X";
int i=0;

viewerType=2;

TEvent event;

if (tagListBox->range == 0) return;

tagListBox->getText(ligne, tagListBox->focused, 254);

errorFichier[0] = 0;
errorMessage[0] = 0;

for (i = 0;ligne[i] != ' ';i++)
	{
	x[0] = ligne[i];
	strcat(errorFichier,x);
	}

for (i++;ligne[i] != ' ';i++)
	{
	x[0] = ligne[i];
	strcat(linenum,x);
	}

for (i+=3;strlen(errorMessage) < 80;i++)
	{
	if (ligne[i] == 0) break;
	x[0] = ligne[i];
	strcat(errorMessage,x);
	}

x[0] = ' ';
for (i=strlen(errorMessage);i<80;i++)
	strcat(errorMessage,x);

errorLineNumber = atoi(linenum);
event.what = evBroadcast;
event.message.command = 1530;
event.message.infoInt = makeFocused;
putEvent(event);
}

void TTaggerWindow::handleEvent(TEvent& event)
{

 char str[256]="";
 char ln[6]="";
 char c[2]="X";
 char before[256]="";
 char after[256]="";
 signed int l;
 int a;

TWindow::handleEvent(event);
if (event.what == evCommand)
	{
    switch (event.message.command)
    	{
    	case 2008:
            curTag = tagListBox->focused;
			if (curTag < tagList->getCount()-1)
				curTag++;
            else
            	curTag=0;
            tagListBox->focusItem(curTag);
        	clearEvent(event);
            break;

        default:
        	break;
        }
    }
if (event.what == evKeyDown)
	{
	switch( event.message.command )
		{
		case kbEnter:
		trackTag(True);
		break;

		case kbDel:
		if (tagList->getCount()==0) break;
		tagList->atRemove(tagListBox->focused);
		update();
		tagListBox->focusItem(tagListBox->focused);
		break;

		case kbGrayPlus:

        if (tagListBox->range == 0) break;

		strcpy(str,(char *)tagList->at(tagListBox->focused));

		for (a=0;str[a] != ' ';a++)
			{
			c[0]=str[a];
			strcat(before,c);
			}

		for (;str[a] == ' ';a++)
			{
			c[0]=str[a];
			strcat(before,c);
			}

		for (;str[a] != ' ';a++)
			{
			c[0]=str[a];
			strcat(ln,c);
			}

		strcat(after,&str[a]);

		l = atoi(ln)+1;
		itoa(l,ln,10);

		sprintf(str,"%s%s%s",before,ln,after);

		l = tagListBox->focused;
		tagList->atRemove(l);
		tagList->atInsert(l,newStr(str));
		update();
		tagListBox->focusItem(l);
		break;


		case kbGrayMinus:

		if (tagListBox->range == 0) break;

		strcpy(str,(char *)tagList->at(tagListBox->focused));

		for (a=0;str[a] != ' ';a++)
			{
			c[0]=str[a];
			strcat(before,c);
			}

		for (;str[a] == ' ';a++)
			{
			c[0]=str[a];
			strcat(before,c);
			}

		for (;str[a] != ' ';a++)
			{
			c[0]=str[a];
			strcat(ln,c);
			}

		strcat(after,&str[a]);

		l = atoi(ln)-1;
		if (l < 1) break;
		itoa(l,ln,10);

		sprintf(str,"%s%s%s",before,ln,after);

		l = tagListBox->focused;
		tagList->atRemove(l);
		tagList->atInsert(l,newStr(str));
		update();
		tagListBox->focusItem(l);
		break;


		default:
		return;
		}
    clearEvent(event);
	}
if (event.what == evBroadcast)
	{
	switch( event.message.command )
		{
		case cmReceivedFocus:
		if (event.message.infoPtr != this) return;
		if (!inMacro)
			{
			inMacro2 = True;
			trackTag(False);
			inMacro = False;
			}
		else
			inMacro = False;
		break;

		case 2002:
			trackTag(False);
			break;

		default:
		return;
		}
	clearEvent(event);
	}
}

/*void TTaggerWindow::draw()
{
draw();
}*/

TTaggerWindow::TTaggerWindow(const int winnum) :
	TWindow( TProgram::deskTop->getExtent(), "Tags", winnum ),
	TWindowInit( &TTaggerWindow::initFrame )
{
	growMode = gfGrowHiX | gfGrowHiY;
	palette = wpCyanWindow;
	options |= ofTileable;
	number = winnum;
	flags |= wfMove | wfGrow | wfClose | wfZoom;

	TRect r = getExtent();
	r.grow(-1,-1);

	insert (tagListBox = new TTaggerList(r,standardScrollBar(sbVertical)));

	tagListBox->newList( tagList );
}

#pragma warn -par
void TTaggerWindow::write( opstream& os )
{
}


void *TTaggerWindow::read( ipstream& is )
{
	return this;
}
#pragma warn .par

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

TStreamableClass RTaggerWindow( TTaggerWindow::name,
				  TTaggerWindow::build,
				  __DELTA(TTaggerWindow)
				);

TTaggerWindow::TTaggerWindow( StreamableInit ) :
	TWindow( streamableInit ),
	TWindowInit( &TTaggerWindow::initFrame )
{
}

void shiftTags( int line, int side )
{
int a,b;
char str[255];
char c[2]="X";
char before[256]="";
char after[256]="";
signed int l;
char ln[6]="";
int test;

for (b=0;b<tagList->getCount();b++)
	{
	strcpy(str, (char *)tagList->at(b));
    before[0]=0;
    after[0]=0;
    ln[0]=0;

	for (a=0;str[a] != ' ';a++)
		{
		c[0]=str[a];
		strcat(before,c);
		}

	for (;str[a] == ' ';a++)
		{
		c[0]=str[a];
		strcat(before,c);
		}

	for (;str[a] != ' ';a++)
		{
		c[0]=str[a];
		strcat(ln,c);
		}

	strcat(after,&str[a]);

	l = atoi(ln)+side;
	itoa(l,ln,10);

    if (side > 0)
    	test = (l >= line);
    else
    	test = (l >= line);

    if (test)
		{
	    sprintf(str,"%s%s%s",before,ln,after);

	    tagList->atRemove(b);
	    tagList->atInsert(b,newStr(str));
        }
    }
}
