// Main.c - Copyright © 1994 Mike Austin

#include <stdio.h>
#include <string.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/gadtools.h>
#include <proto/multiuser.h>
#include <pragmas/nofrag_pragmas.h>
#include <proto/nofrag_protos.h>
#include "MFileMode.h"
#include "GUI.h"

const UBYTE	*Version = "$VER: MFileMode 0.9 "__AMIGADATE__;
__aligned struct FileInfoBlock	FileInfo;
struct muBase		*muBase;
struct Library		*NoFragBase;
struct List			FileList;
struct muUserInfo	*UserInfo;
struct muGroupInfo	*GroupInfo;
struct MemoryChain	*MemChain;
UWORD				EntryNum = 0;
UBYTE				**FileNames;
UBYTE				Path[81] = "";
BOOL				Changed = FALSE;
BOOL				Selected = FALSE;

struct EasyStruct	EasyReq = {
	sizeof(struct EasyStruct),
	0,
	"MFileMode",
	"%s %s",
	"OK"
};

long main(void)
{
	ULONG				Signals, WinSig;
	BOOL				Running = TRUE;

	NewList(&FileList);

	if(Init())
	{
		if(!SetupScreen())
		{
			if(!OpenMainWindow())
			{
				MainRender();

				WinSig = 1L << MainWnd->UserPort->mp_SigBit;

				LoadVolumes(&FileList);

				while(Running)
				{
					Signals = Wait(WinSig | SIGBREAKF_CTRL_C);

					if(Signals & WinSig)
					{
						Running = HandleMainIDCMP();
					}
					else if(Signals & SIGBREAKF_CTRL_C)
					{
						Running = FALSE;
					}
				}

				CloseMainWindow();
			}
			else
				AlertUser(MainWnd, "Can't open window", "");

			CloseDownScreen();
		}
		else
			AlertUser(MainWnd, "Can't set up screen", "");

		FreeList(&FileList);

		Cleanup();
	}

	return 0;
}

BOOL Init(VOID)
{
	if(muBase = (struct muBase *)OpenLibrary("multiuser.library", 39))
	{
		if(NoFragBase = OpenLibrary("nofrag.library", 2))
		{
			if(MemChain = GetMemoryChain(4096))
			{
				if(UserInfo = muAllocUserInfo())
				{
					if(GroupInfo = muAllocGroupInfo())
					{
						return TRUE;
					}

					muFreeGroupInfo(GroupInfo);
				}
				else
					AlertUser(NULL, "Can't allocate user info", "");

				FreeMemoryChain(MemChain, TRUE);
			}
			else
				AlertUser(NULL, "Can't get memory chain", "");

			CloseLibrary(NoFragBase);
		}
		else
			AlertUser(NULL, "Can't open nofrag.library", "2.0");

		CloseLibrary((struct Library *)muBase);
	}
	else
		AlertUser(NULL, "Can't open multiuser.library ", "39");

	return FALSE;
}

VOID Cleanup(VOID)
{
	muFreeGroupInfo(GroupInfo);
	muFreeUserInfo(UserInfo);
	FreeMemoryChain(MemChain, TRUE);
	CloseLibrary(NoFragBase);
	CloseLibrary((struct Library *)muBase);
}

int MainCloseWindow(VOID)
{
	WriteData();

	return FALSE;
}

VOID WriteData(VOID)
{
	struct DevProc	*DevProc;
	BPTR			FileLock;
	UBYTE			TempPath[81];

	if(Changed && Selected)
	{
		strcpy(TempPath, Path);
		AddPart(TempPath, FileNames[EntryNum], 80);
		ReadGadgets(&FileInfo);
		muSetProtection(TempPath, FileInfo.fib_Protection);

		if(DevProc = GetDeviceProc(TempPath, NULL))
		{
			if(FileLock = Lock(TempPath, ACCESS_READ))
			{
				if(!DoPkt(DevProc->dvp_Port, ACTION_SET_OWNER, 0L, FileLock,
						MKBADDR(NULL), (LONG)UserInfo->uid << 16 |
						(LONG)UserInfo->gid, 0L))
				{
					AlertUser(MainWnd, "Can't set owner", "");
				}

				UnLock(FileLock);
			}
			else
				AlertUser(MainWnd, "Can't lock file", TempPath);

			FreeDeviceProc(DevProc);
		}
		else
			AlertUser(MainWnd, "Can't get device proccess", TempPath);

		Changed = FALSE;
	}
}

VOID FreeList(struct List *List)
{
	struct Node	*Node = List->lh_Head;
	struct Node	*Next;

	while(Next = Node->ln_Succ)
	{
		FreeVecItem(MemChain, Node);

		Node = Next;
	}

	FreeVecItem(MemChain, FileNames);

	NewList(&FileList);
}

UBYTE *BSTR2CSTR(BSTR BString)
{
	static UBYTE Buffer[255];
	static UBYTE *String;

	String = BADDR(BString);
	CopyMem(&(String[1]), Buffer, String[0]);
	Buffer[String[0]] = '\0';

	return Buffer;
}

VOID AlertUser(struct Window *Win, UBYTE *String, UBYTE *Arg)
{
	struct Requester	Req;

	if(Win)
	{
		InitRequester(&Req);

		if(Request(&Req, Win))
		{
			EasyRequest(MainWnd, &EasyReq, NULL, String, Arg);

			EndRequest(&Req, Win);
		}
	}
	else
	{
		EasyRequest(MainWnd, &EasyReq, NULL, String, Arg);
	}
}
