/*-
 * RIPCORD.C
 *
 * The xpkdisk.device code that takes care of disk space availability.
 *
 * $Id: ripcord.c,v 1.1 1993/11/08 13:29:16 Rhialto Rel $
 * $Log: ripcord.c,v $
 * Revision 1.1  1993/11/08  13:29:16  Rhialto
 * Initial revision
 *
 *
 * This code is (C) Copyright 1993 by Olaf Seibert. All rights reserved.
 * May not be used or copied without a licence.
-*/

#include <string.h>
#include <stdio.h>
#include "xpkdisk.h"
#include <intuition/intuitionbase.h>
#include <clib/intuition_protos.h>

extern struct DosLibrary   *DOSBase;
extern struct IntuitionBase *IntuitionBase;

/*#undef DEBUG			*/
#ifdef DEBUG
#   include "syslog.h"
#else
#   define	debug(x)
#endif

static const char   Ripcord[] = XPKDISKDIR "Ripcord";

int
RipTryAbort(UNIT *unit, int ripcord)
{
    static struct EasyStruct es = {
	sizeof(es),
	0,
	"xpkdisk Request",
	"Panic!!!\n" XPKDISKDIR " medium is (nearly) full!\n%s",
	NULL
    };
    char	   *extra;
    int 	    choice;

    if (ripcord) {
	extra = "(but the ripcord is still there)";
	es.es_GadgetFormat = "Rip Cord|Try Anyway|Abort";
    } else {
	extra = "(and no ripcord is present)";
	es.es_GadgetFormat = "Try Anyway|Abort";
    }

    choice = EasyRequest(NULL, &es, NULL, extra);
    if ((ripcord == 0) && (choice == 1))
	choice = 2;
}

Prototype int MakeRipcord(UNIT *unit);

int
MakeRipcord(UNIT *unit)
{
    void	   *v;
    BPTR	    fh;
    long	    length;

    /*
     * Reserve space for 2 tracks, and add 1 sector for the file header
     * of the second track.
     */
    length = XD_BPS + (2 * unit->xu_TrackLen);
    unit->xu_RipcordBlocks = length / XD_BPS;

    v = AllocMem(1024, MEMF_ANY | MEMF_CLEAR);
    if (v) {
	if (fh = Open(Ripcord, MODE_READWRITE)) {
	    int 	    i;

	    Seek(fh, 0, OFFSET_END);
	    i = (Seek(fh, 0, OFFSET_CURRENT) - length) / 1024;
	    while (i > 0) {
		Write(fh, v, 1024);
		i--;
	    }
	    Close(fh);
	}
	FreeMem(v, 1024);
    }
    return v && fh;
}

int
DeleteRipcord(UNIT *unit)
{
    return DeleteFile(Ripcord);
}

Prototype int CheckRipcord(UNIT *unit);

int
CheckRipcord(UNIT *unit)
{
    __aligned struct InfoData infodata;
    BPTR	    fl;
    BPTR	    ripcord;
    int 	    choice;
    int 	    result = 1;

    ripcord = Lock(Ripcord, SHARED_LOCK);
    UnLock(ripcord);
    fl = Lock("", SHARED_LOCK);
    if (Info(fl, &infodata)) {
	if ((infodata.id_NumBlocks - infodata.id_NumBlocksUsed) <
						unit->xu_RipcordBlocks) {
	    /* Disk nearly full */
	    if (IntuitionBase->LibNode.lib_Version < 37) {
		choice = 1;
	    } else {  /* 1  2  0 */
		choice = RipTryAbort(unit, ripcord);
	    }
	    switch (choice) {
	    case 0:	/* Abort */
		result = 0;
		break;
	    case 1:	/* Rip Cord */
		DeleteRipcord(unit);
	    case 2:	/* Try Anyway */
		result = 1;
		break;
	    }
	}
    }
    UnLock(fl);
    return result;
}

