//
// HTMLEditor V1.0
// ---------------
//
// Készítette:
// -----------
// Klingl János      /Cyber/
// Szekeres Károly   /Szeka/
// 
// Ez a program a Kandó Kálmán Műszaki Főiskola Számítógéptechnikai Intézetének
// keretein belül, mint féléves Project feladat került elkészítésre.
// 
// Köszönetek:
// -----------
// Stefan Stuntz     /A MUI írójának/
// Dirk Holtwick  /A HTMLtext írójának/
// Allan Odgaard  /TextEditor írójának/
// Eric Totel     /MUIBuilder írájának/
// És minden olyan embernek, aki örömmel használja ezt a programot.
//

// Szükséges include-ok beillesztése.

#include <workbench/startup.h>
#include <clib/alib_protos.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/asl.h>
#include <proto/utility.h>
#include <proto/muimaster.h>
#include <proto/icon.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <Rexx/Storage.h>
#include <Proto/RexxSysLib.h>

// HTMLtext.mcc
#include <mui/HTMLtext_mcc.h>

// TextEditor.mcc
#include <MUI/TextEditor_mcc.h>

#define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
#define cucc __saveds __asm

extern struct Library *SysBase;
// a buttonokat valami fiktív értéktől kezdve sorszámozzuk, hogy
// később meg tudjuk különböztetni őket.
enum {relod_p=897,refrs_p,preview_p,save_p,new_p,fromurl_p,
	  h1_p,h2_p,h3_p,h4_p,h5_p,h6_p,html_p,body_p,center_p,title_p,image_p,link_p,br_p,hr_p,p_p,
	  };
//veremméret lefixálása (HTMLtext igényli)
LONG __stack = 8192;

APTR app;	//aplikáció
APTR window;//ablak
APTR str;	//szövegbeíró
APTR html;  //html viewer
APTR scroll;//és annak scroller-ja
APTR url;   //url cím vagy lokális cím kijelzésének objecte

LONG cmap[8];

char empty[]="";//újrakezdés-koz ezt töltjük be.

// hiba esetén ez a változó jelzi, hogy hiba történt(texteditor használja)
int error=0;
// ha (error==1) igaz, akkor -> hiba történt
// !!Figyelem a tesztelendő utasítás elé kinullázás(error=0) szükséges.

/// AppMsg Funkciók a MUI-nak
__saveds __asm LONG AppMsgFunc(register __a2 APTR obj, register __a1 struct AppMessage **x)
{

	struct WBArg *ap;
	struct AppMessage *amsg = *x;
	static char buf[256];

	if(amsg->am_NumArgs)
	{
		ap=amsg->am_ArgList;
		NameFromLock(ap->wa_Lock,buf,sizeof(buf));
		AddPart(buf,ap->wa_Name,sizeof(buf));
		set(obj,MUIA_HTMLtext_URL,buf);
	}

	return(0);
}

cucc ULONG TextEditor_Dispatcher (register __a0 struct IClass *cl, register __a2 Object *obj, register __a1 struct MUIP_TextEditor_HandleError *msg)
{

// A "texteditor.mcc"-vel való kapcsolat fenntartásához szükséges
// metódusok lekezelését végző függvények

	switch(msg->MethodID)
	{
		case MUIM_Show:
		{
				struct ColorMap *cm = muiRenderInfo(obj)->mri_Screen->ViewPort.ColorMap;

			cmap[0] = ObtainBestPenA(cm, 0x00<<24, 0x00<<24, 0x00<<24, NULL);
			cmap[1] = ObtainBestPenA(cm, 0xff<<24, 0xff<<24, 0xff<<24, NULL);
			cmap[2] = ObtainBestPenA(cm, 0xff<<24, 0x00<<24, 0x00<<24, NULL);
			cmap[3] = ObtainBestPenA(cm, 0x00<<24, 0xff<<24, 0x00<<24, NULL);
			cmap[4] = ObtainBestPenA(cm, 0x00<<24, 0xff<<24, 0xff<<24, NULL);
			cmap[5] = ObtainBestPenA(cm, 0xff<<24, 0xff<<24, 0x00<<24, NULL);
			cmap[6] = ObtainBestPenA(cm, 0x00<<24, 0x00<<24, 0xff<<24, NULL);
			cmap[7] = ObtainBestPenA(cm, 0xff<<24, 0x00<<24, 0xff<<24, NULL);
			break;
		}

		case MUIM_Hide:
		{
				struct ColorMap *cm = muiRenderInfo(obj)->mri_Screen->ViewPort.ColorMap;
				int c;

			for(c = 0; c < 8; c++)
			{
				if(cmap[c] >= 0)
				{
					ReleasePen(cm, cmap[c]);
				}
			}
			break;
		}

		case MUIM_DragQuery:
		{
			return(TRUE);
		}

		case MUIM_DragDrop:
		{
			break;
		}

	   // hibák lekezelése
		case MUIM_TextEditor_HandleError:
		{
				char *errortxt = NULL;
			error = 1;

			switch(msg->errorcode)
			{

				case Error_ClipboardIsEmpty:
					errortxt = "\33cThe clipboard is empty.";
					break;
				case Error_ClipboardIsNotFTXT:
					errortxt = "\33cThe clipboard does not contain text.";
					break;
				case Error_MacroBufferIsFull:
					break;
				case Error_MemoryAllocationFailed:
					break;
				case Error_NoAreaMarked:
					errortxt = "\33cNo area marked.";
					break;
				case Error_NoMacroDefined:
					break;
				case Error_NothingToRedo:
					errortxt = "\33cNothing to redo.";
					break;
				case Error_NothingToUndo:
					errortxt = "\33cNothing to undo.";
					break;
				case Error_NotEnoughUndoMem:
					errortxt = "There is not enough memory\nto keep the undo buffer.\n\nThe undobuffer is lost.";
					break;
				case Error_StringNotFound:
					break;
				case Error_NoBookmarkInstalled:
					errortxt = "There is no bookmark installed!";
					break;
				case Error_BookmarkHasBeenLost:
					errortxt = "Your bookmark has unfortunately been lost.";
					break;
			}
			if(errortxt)
			{
				MUI_Request(app, window, 0L, NULL, "Continue", errortxt);
			}
			break;
		}
	}
	return(DoSuperMethodA(cl, obj, (Msg)msg));
}

// a texteditor gadget mutatója

Object *editorgad=0;

// File töltése a String.Gadget-ben szereplő helyről.
void refresh(void)
{
	char *miaz;
	FILE *fh;
	char *fip;
	int len;

	get(str,MUIA_String_Contents,&miaz);

	if (fh=fopen(miaz,"r"))
	{
		fseek(fh,0,SEEK_END);
		len=ftell(fh);
		fseek(fh,0,SEEK_SET);
		fip=(char*)malloc(len+1);
		fread(fip,1,len,fh);
		fclose(fh);
		fip[len]=0;
		set(editorgad,MUIA_TextEditor_Contents,fip);
		free(fip);
	};
}

// File mentése a String.Gadget-ben szereplő helyre.
void savefile(void)
{
	char *miaz;
	STRPTR savetxt;
	FILE *fh;

	get(str,MUIA_String_Contents,&miaz);

	savetxt = (STRPTR)DoMethod(editorgad, MUIM_TextEditor_ExportText);
	if (fh=fopen(miaz,"w"))
	{
		fwrite(savetxt,1,strlen(savetxt),fh);
		fclose(fh);
	};
	free(savetxt);
}

// A TextEditor.Gadget-tel Arexx interface-en keresztül tudunk beszélgetni
// Ez a függvény a HTML "tag"-ek behelyezését végzi
// A kijelölt szöveg előtt a "tag"-et, mögé pedig mögé pedig
// a "tag" végét jelző "/"-est kulcsszót kell beilleszteni.
// Ez úgy csinálja meg a program, hogy a CUT paranccsal a clipboard-ba helyezzük
// a "tag"-elendő szöveget, majd beírjuk a kezdőteget. Ezután PASTE segitségével
// visszaírjuk az előzőleg vágólapra(clipboard) helyezett szöveget. Aztán beillesztjük
// a tagvég jelet.
void puttxt(char *tx1,char *tx2)
{
	char buf[120];
	error = 0;
	DoMethod(editorgad, MUIM_TextEditor_ARexxCmd, "CUT");
	if (error==0)
	{
	 strcpy(buf,"TEXT ");
	 strcat(buf,tx1);
	 DoMethod(editorgad, MUIM_TextEditor_ARexxCmd, buf);
	 DoMethod(editorgad, MUIM_TextEditor_ARexxCmd, "PASTE");
	 strcpy(buf,"TEXT ");
	 strcat(buf,tx2);
	 DoMethod(editorgad, MUIM_TextEditor_ARexxCmd, buf);
	}
}

// A Mester library-ra mutató pointer. Ez tölti be a mcc-ket()
// És menti vezérli az egész megjelenítést.

struct Library *MUIMasterBase;

// Main
int main(int argc,char *argv[])
{
	char *ural;
	STRPTR ptr;

   // Gobok mutatói
	Object *new,*relod,*preview,*save,*h1,*h2,*h3,*h4,*h5,*h6;
	Object *htmlt,*bodyt,*centert,*titlet,*fromurl,*imaget,*linkt,*brt,*hrt,*pt;

   // az editor rész deklarációja
	struct	MUI_CustomClass	*editor_mcc;

	Object *slider=0;

	struct   Library *IntuitionBase;
	int      ret=RETURN_ERROR;
	static   const struct Hook AppMsgHook = { { NULL,NULL },(VOID *)AppMsgFunc,NULL,NULL };

	if(IntuitionBase = OpenLibrary("intuition.library", 36))
	{
		if(MUIMasterBase = OpenLibrary(MUIMASTER_NAME, 13))
		{
		  if(editor_mcc = MUI_CreateCustomClass(NULL, "TextEditor.mcc", NULL, 0, (void *)TextEditor_Dispatcher))
		  {
			ULONG signals;
			BOOL running = TRUE;
		   // Csinálunk egy aplikációt(ez maga a program).
			app = ApplicationObject,
				MUIA_Application_Title      , "HTMLEdit",
				MUIA_Application_Version    , "$VER: HTMLEdit 1.0 " __AMIGADATE__,
				MUIA_Application_Copyright  , "(C)opyright by Best Team 1998",
				MUIA_Application_Author     , "Szeka&Cyber",
				MUIA_Application_Description, "Makes creating HTML pages easily.",
				MUIA_Application_Base       , "HTMLEDIT",

				SubWindow, window = WindowObject,
					MUIA_Window_Title, "HTMLEdit © Best Team Szeka&Cyber 1998",
					MUIA_Window_ID   , MAKE_ID('H','T','M','L'),
					MUIA_Window_UseRightBorderScroller, TRUE,
					MUIA_Window_UseBottomBorderScroller, TRUE,
					MUIA_Window_AppWindow, TRUE,

					WindowContents, VGroup,

						Child, str = StringObject,
							StringFrame,
							MUIA_FrameTitle,"HTML-Page to Edit",
							MUIA_CycleChain, 1,
							MUIA_String_MaxLen, 1024,
							End,

						Child, url = TextObject,
							TextFrame,
							MUIA_FrameTitle,"URL",
							MUIA_Font, MUIV_Font_Tiny,
							MUIA_Background, MUII_TextBack,
							MUIA_Text_Contents, ">>> No URL <<<",
							End,

						Child, scroll = ScrollgroupObject,
							MUIA_CycleChain, 1,
							MUIA_Scrollgroup_UseWinBorder, TRUE,
							MUIA_Scrollgroup_Contents, html = HTMLtextObject,
								TextFrame,
								End,
							End,
						Child, HGroup, // Gombok lehelyezése
							Child, new=MUI_MakeObject(MUIO_Button,"_New"),
							Child, fromurl=MUI_MakeObject(MUIO_Button,"_FromURL"),
							Child, relod=MUI_MakeObject(MUIO_Button,"Re_load"),
							Child, preview=MUI_MakeObject(MUIO_Button,"Pre_view"),
							Child, save=MUI_MakeObject(MUIO_Button,"_Save"),
							End,
						Child, HGroup,
							Child, h1=MUI_MakeObject(MUIO_Button,"H_1"),
							Child, h2=MUI_MakeObject(MUIO_Button,"H_2"),
							Child, h3=MUI_MakeObject(MUIO_Button,"H_3"),
							Child, h4=MUI_MakeObject(MUIO_Button,"H_4"),
							Child, h5=MUI_MakeObject(MUIO_Button,"H_5"),
							Child, h6=MUI_MakeObject(MUIO_Button,"H_6"),
							End,
						Child, HGroup,
							Child, htmlt=MUI_MakeObject(MUIO_Button,"_Html"),
							Child, titlet=MUI_MakeObject(MUIO_Button,"_Title"),
							Child, bodyt=MUI_MakeObject(MUIO_Button,"B_ody"),
							Child, centert=MUI_MakeObject(MUIO_Button,"_Center"),
							Child, imaget=MUI_MakeObject(MUIO_Button,"_Image"),
							Child, linkt=MUI_MakeObject(MUIO_Button,"_Link"),
							Child, hrt=MUI_MakeObject(MUIO_Button,"H_R"),
							Child, brt=MUI_MakeObject(MUIO_Button,"_BR"),
							Child, pt=MUI_MakeObject(MUIO_Button,"_P"),
							End,
						Child, HGroup,
							MUIA_Group_Spacing, 0,
							Child, editorgad = NewObject(editor_mcc->mcc_Class, NULL,
								MUIA_TextEditor_Slider, slider,
								MUIA_TextEditor_ColorMap, cmap,
								MUIA_CycleChain, TRUE,
								End,
							Child, slider = ScrollbarObject,
								End,
							End,
						Child, TextObject,
							TextFrame,
							MUIA_Font, MUIV_Font_Tiny,
							MUIA_Background, MUII_TextBack,
							MUIA_Text_Contents, "The Forcers Team Homepage: http://mosogep.rulez.org/~forcers",
							End,
						End,
					End,
				End;

			if(app)
			{
			  //potit hozzárendeljük a texteditorhoz.
				set(editorgad,MUIA_TextEditor_Slider, slider);
			  //alapra(index.html) beállítjuk a filenevet.
				set(str,MUIA_String_Contents,"index.html");


			  //Automatikus Notifikációk beállítása
				DoMethod(relod, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, relod_p);
				DoMethod(preview, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, preview_p);
				DoMethod(save, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, save_p);
				DoMethod(new, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, new_p);

				DoMethod(h1, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, h1_p);
				DoMethod(h2, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, h2_p);
				DoMethod(h3, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, h3_p);
				DoMethod(h4, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, h4_p);
				DoMethod(h5, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, h5_p);
				DoMethod(h6, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, h6_p);

				DoMethod(fromurl, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, fromurl_p);
				DoMethod(htmlt, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, html_p);
				DoMethod(titlet, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, title_p);
				DoMethod(bodyt, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, body_p);
				DoMethod(centert, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, center_p);
				DoMethod(imaget, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, image_p);
				DoMethod(linkt, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, link_p);
				DoMethod(hrt, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, hr_p);
				DoMethod(brt, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, br_p);
				DoMethod(pt, MUIM_Notify, MUIA_Pressed, TRUE,
					app, 2, MUIM_Application_ReturnID, p_p);

				DoMethod(window, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
					app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);

				DoMethod(html,MUIM_Notify,MUIA_AppMessage,MUIV_EveryTime,
					html,3,MUIM_CallHook,&AppMsgHook,MUIV_TriggerValue);

				DoMethod(html,MUIM_Notify,MUIA_HTMLtext_Title,MUIV_EveryTime,
					window,3,MUIM_Set,MUIA_Window_Title,MUIV_TriggerValue);

				DoMethod(html,MUIM_Notify,MUIA_HTMLtext_URL,MUIV_EveryTime,
					url,3,MUIM_Set,MUIA_Text_Contents,MUIV_TriggerValue);

				set(window,MUIA_Window_ActiveObject,str);
				set(window,MUIA_Window_DefaultObject,str);

				set(window,MUIA_Window_Open,TRUE);

				if (argc>1)
				 {
					set(html,MUIA_HTMLtext_URL,argv[1]);
					refresh();
				 }
				while (running)
				{
					switch(DoMethod(app,MUIM_Application_Input,&signals))
					{
						case MUIV_Application_ReturnID_Quit:
							running = FALSE;
							break;

					   //Gombok figyelése
						case relod_p:
							get(str,MUIA_String_Contents,&ural);
							set(html,MUIA_HTMLtext_URL,ural);
							refresh();
							break;
						case fromurl_p:
							get(html,MUIA_HTMLtext_URL,&ural);
							set(str,MUIA_String_Contents,ural);
							refresh();
							break;
						case preview_p:
							ptr=(STRPTR)DoMethod(editorgad,MUIM_TextEditor_ExportText);
							set(html,MUIA_HTMLtext_Contents,ptr);
							free(ptr);
							break;
						case save_p:
							savefile();
							break;
						case new_p:
							set(html,MUIA_HTMLtext_Contents,empty);
							set(editorgad,MUIA_TextEditor_Contents,empty);
							break;
					   //"Tag"-ek beillesztése
						case html_p:
							puttxt("<HTML>","</HTML>");
							break;
						case body_p:
							puttxt("<BODY>","</BODY>");
							break;
					   //Módváltó "tag"-ek
						case h1_p:
							puttxt("<H1>","</H1>");
							break;
						case h2_p:
							puttxt("<H2>","</H2>");
							break;
						case h3_p:
							puttxt("<H3>","</H3>");
							break;
						case h4_p:
							puttxt("<H4>","</H4>");
							break;
						case h5_p:
							puttxt("<H5>","</H5>");
							break;
						case h6_p:
							puttxt("<H6>","</H6>");
							break;
						case center_p:
							puttxt("<CENTER>","</CENTER>");
							break;
						case title_p:
							puttxt("<TITLE>","</TITLE>");
							break;
					   //Ezek is "tag"-ek, de ezek szimpla vezérlő-"tag"-ek
						case hr_p:
							DoMethod(editorgad, MUIM_TextEditor_ARexxCmd, "TEXT <HR>");
							break;
						case br_p:
							DoMethod(editorgad, MUIM_TextEditor_ARexxCmd, "TEXT <BR>");
							break;
						case image_p:
							puttxt("<IMG SRC=\"","\">");
							break;
						case link_p:
							puttxt("<A HREF=\"","\"> </A>");
							break;
						case p_p:
							puttxt("<P>","</P>");
							break;
						default:
							break;
					}
					if(running && signals)
						Wait(signals);
				}

				set(window, MUIA_Window_Open, FALSE);

				MUI_DisposeObject(app);

				ret = RETURN_OK;
			} else {
				puts("Could not open application!");
				ret = RETURN_FAIL;
			}

		  }
		  CloseLibrary(MUIMasterBase);
		} else {
			puts("Could not open muimaster.library v13!");
			ret = RETURN_FAIL;
		}

		CloseLibrary(IntuitionBase);
	} else {
		puts("Could not open intuition.library v36!");
		ret = RETURN_FAIL;
	}
	return(ret);
}
