/* main.c -- Amiga specific setup and cleanup functions etc.
 * Copyright (C) 1994  Torsten Klein
 *
 * This file is part of ASpringies, a mass and spring simulation system for the Amiga
 *
 * ASpringies 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 1, or (at your option)
 * any later version.
 *
 * ASpringies 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 ASpringies; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: main.c,v 2.9 1994/08/19 11:49:05 Torsten_Klein Exp $  
 */

#include <exec/memory.h>

#include "main.h"
#include "defs.h"
#include "obj.h"

struct Library                  *TimerBase, *MUIMasterBase;
struct Window			*anim_wnd;
struct Screen                   *anim_scr;
struct RastPort                 *anim_rport[ANIM_BUFS];

LONG __oslibversion = 37, __stack = 8192;

static int    display_open;
static struct RasInfo             *anim_rinfo;
static struct BitMap              *anim_bmap[ANIM_BUFS];
static struct Layer_Info          *anim_linfo[ANIM_BUFS];
static struct Layer               *anim_layer[ANIM_BUFS];
static struct IORequest            iORequest;
static struct FileRequester       *AslFileReq;
static struct ScreenModeRequester *AslScrReq;

/* MUI stuff
 */
APTR 
  AP_ASpringies,
  WI_ASpringies,

  RA_Mode,

  CY_Force,
  PG_Force,

  CK_DrawSpr,    CK_Action,       CK_FixedMass,    CK_AdaptTStep,
  CK_GravActive, CK_CenterActive, CK_PtAttrActive, CK_WallFActive,
  CK_WallTop,    CK_WallLeft,     CK_WallRight,    CK_WallBottom,

  BT_SelAll,     BT_SetRLen,      BT_SetCenter,

  SL_Grid,

  ST_Mass,       ST_Elas,         ST_Kspr,         ST_Kdmp,
  ST_Visc,       ST_Stic,         ST_Step,         ST_Prec, 
  ST_GravGrav,   ST_GravDir,      ST_CenterMagn,   ST_CenterDamp, 
  ST_PtAttrMagn, ST_PtAttrExpo,   ST_WallFMagn,    ST_WallFExpo,

  TX_Fps;
     
/* ******************************************************************** */
     
int  CXBRK(void) { return(0); } 

void chkabort(void)  {}

main(int argc, char **argv)
{
  FAILOPEN(MUIMASTER_NAME,
	   MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN));
  SetUpMui();

  FAILOPEN("timer.device (UNIT_MICROHZ)",
	   !OpenDevice("timer.device", UNIT_MICROHZ, &iORequest, 0));
  TimerBase = (struct Library *)iORequest.io_Device;

  FAILOPEN("Asl file requester", AslFileReq = MUI_AllocAslRequestTags
	   (ASL_FileRequest,
	    ASLFR_InitialDrawer,             "PROGDIR:lib/",
	    ASLFR_InitialPattern,            "#?.xsp",
	    ASLFR_DoPatterns,                TRUE,
	    TAG_DONE));

  if (!(AslScrReq = MUI_AllocAslRequestTags
	   (
	    ASL_ScreenModeRequest,
	    ASLSM_InitialDisplayID,     DEFAULT_MONITOR_ID | HIRESLACE_KEY,
	    ASLSM_InitialOverscanType,  OSCAN_STANDARD,
	    ASLSM_InitialDisplayWidth,  640,
	    ASLSM_InitialDisplayHeight, 548,
	    ASLSM_TitleText,            "Animation screen mode",
	    ASLSM_DoWidth,              TRUE,
	    ASLSM_DoHeight,             TRUE,
	    ASLSM_DoOverscanType,       TRUE,
	    ASLSM_DoAutoScroll,         TRUE,
	    TAG_DONE
	    )))
    DoMethod(AP_ASpringies, MUIM_Application_SetMenuState, ID_ME_ScreenMode, FALSE);

  OpenAnimDisplay(FALSE);
  DoMethod(WI_ASpringies, MUIM_Window_ScreenToFront);
  DoMethod(WI_ASpringies, MUIM_Window_ToFront); 
  set(WI_ASpringies, MUIA_Window_Activate, TRUE);

  new_main();

  main_fail(NULL, NULL, 0);
}

  /* ******************************************************************** */

void OpenAnimDisplay(boolean request)
{
  int i;

  if (request)
    MUI_AslRequestTags(AslScrReq,TAG_DONE);

  FAILOPEN("animation screen", anim_scr = OpenScreenTags
	   (NULL,
	    SA_DisplayID,     AslScrReq->sm_DisplayID,
	    SA_Width,         AslScrReq->sm_DisplayWidth,
	    SA_Height,        AslScrReq->sm_DisplayHeight,
	    SA_Overscan,      AslScrReq->sm_OverscanType,
	    SA_AutoScroll,    AslScrReq->sm_AutoScroll,
	    SA_Depth,         1,
	    SA_Type,          CUSTOMSCREEN | SCREENQUIET | SCREENBEHIND,
	    SA_Title,         "ASpringies animation screen",
	    TAG_DONE
	    ));
  
  FAILOPEN("animation window", anim_wnd = OpenWindowTags
	   (NULL,
	    WA_Width,         anim_scr->Width,
	    WA_Height,        anim_scr->Height,
	    WA_IDCMP,         IDCMP_MOUSEBUTTONS | IDCMP_VANILLAKEY
	                      | IDCMP_MOUSEMOVE  | IDCMP_RAWKEY,
	    WA_Flags,         WFLG_BORDERLESS    | WFLG_RMBTRAP | WFLG_NOCAREREFRESH,
	    WA_CustomScreen,  anim_scr,
	    WA_AutoAdjust,    TRUE,
	    WA_MouseQueue,    1,
	    TAG_DONE
	    ));

  anim_rport[0] = anim_wnd->RPort;
  anim_bmap[0]  = anim_rport[0]->BitMap;
  anim_rinfo    = anim_scr->ViewPort.RasInfo;

  for (i=1; i<ANIM_BUFS; i++) {
    FAILOPEN("BitMap structure for backbuffer", 
	     anim_bmap[i] = AllocMem(sizeof(struct BitMap), MEMF_CLEAR));

    InitBitMap(anim_bmap[i],1,(LONG)anim_scr->Width, (LONG)anim_scr->Height);

    FAILOPEN("raster for backbuffer BitMap", 
	     anim_bmap[i]->Planes[0] = AllocRaster((ULONG)anim_scr->Width,
						   (ULONG)anim_scr->Height));

    FAILOPEN("LayerInfo for backbuffer", anim_linfo[i] = NewLayerInfo());

    FAILOPEN("BehindLayer for backbuffer",
	     anim_layer[i] = CreateBehindLayer(anim_linfo[i], anim_bmap[i], 0, 0,
					       anim_scr->Width-1, anim_scr->Height-1,
					       LAYERSIMPLE | LAYERBACKDROP, NULL));
    anim_rport[i] = anim_layer[i]->rp;
  }
  display_open=TRUE;
}

/* ******************************************************************** */

void CloseAnimDisplay(void)
{
  int i;
  
  if (display_open) ShowView(0);
  for (i=1; i<ANIM_BUFS; i++) {
    if (anim_layer[i])           DeleteLayer(0, anim_layer[i]);
    WaitBlit();
    if (anim_linfo[i])           DisposeLayerInfo(anim_linfo[i]);
    if (anim_bmap[i] && anim_bmap[i]->Planes[0]) {
      FreeRaster(anim_bmap[i]->Planes[0], (ULONG)anim_scr->Width, 
		 (ULONG)anim_scr->Height);
      FreeMem(anim_bmap[i], sizeof(struct BitMap));
    }
  }
  if (anim_wnd)    CloseWindow(anim_wnd);
  if (anim_scr)    CloseScreen(anim_scr);
}


/* ******************************************************************** */

void ShowView(int n)
{
  anim_scr->RastPort.BitMap = anim_rinfo->BitMap = anim_bmap[n];
  MakeScreen(anim_scr);
  RethinkDisplay();
}      

/* ******************************************************************** */

void main_fail(char *what, char *where, int whatline)
{
  CloseAnimDisplay();
  if (AslScrReq)     MUI_FreeAslRequest(AslScrReq);
  if (AslFileReq)    MUI_FreeAslRequest(AslFileReq);
  CloseDevice(&iORequest);
  if (AP_ASpringies) MUI_DisposeObject(AP_ASpringies);  
  CloseLibrary(MUIMasterBase);

  if (what) {
    fprintf(stderr, "*** ASPRINGIES FAILED to allocate %s in file %s, line %d\n",
	    what, where, whatline);
    exit(20);
  }
  exit(0);
}

/* ******************************************************************** */

void DoInfo(void)
{
  static char
    *InfoText = "\
\033u\033c\033bASpringies\033n\033u - an interactive mass and spring simulator\
\n\
\nCopyright (c) 1994 by Torsten Klein (torstenk@techfak.uni-bielefeld.de)\
\n\033n\033l\
\nbased upon 'xspringies' by Douglas DeCarlo (dd2i+@andrew.cmu.edu) et al.\
\n\
\n\033bASpringies comes with ABSOLUTELY NO WARRANTY; for details see\
\nnode 'Disclaimer' in the online help system.  This is free software, and you\
\nare welcome to redistribute it under certain conditions; please read the\
\nfile 'COPYING' for details.\033n\
\n\
\nASpringies features a context sensitive hypertext help system.\
\nPlease press the <Help> key now to see its table of contents.\
\n\
\n\033iPressing the <Help> key while the pointer is above a group of gadgets or a\
\nmenu will pop up the corresponding page of the manual.";

 MUI_Request(AP_ASpringies, WI_ASpringies, 0, "Program information", "*Ok", InfoText);
}

/* ******************************************************************** */

void FileIO(int command)
{
  static char filename[MAXPATHLEN];

  struct Window        *window;
  char                 title[30]="Select a file to ";

  switch(command)
    {
    case F_LOAD   : strcat(title, "load...");   break;
    case F_INSERT : strcat(title, "insert..."); break;
    case F_SAVEAS : 
    case F_SAVE   : strcat(title, "save...");    break;
    }

  get(WI_ASpringies, MUIA_Window_Window, &window);
  
  if ((command != F_SAVE) || !strlen(filename)) {
    if (MUI_AslRequestTags
	(
	 AslFileReq, 
	 ASLFR_Window,          window,
	 ASLFR_TitleText,       title,
	 ASLFR_DoSaveMode,      (command==F_SAVE),
	 TAG_DONE)) {
      strncpy(filename, AslFileReq->fr_Drawer,  sizeof(filename)-1);
      AddPart(filename, AslFileReq->fr_File,    sizeof(filename)-1);
      if (strlen(filename) && !strstr(filename, ".xsp")) strcat(filename, ".xsp");
    } else return;
  }
  if (!file_command(filename, command)) {
    MUI_Request(AP_ASpringies, WI_ASpringies, 0,
		"ASpringies - Error", "*Ok", "Unable to perform file operation!");
    *filename = NULL;
  }
}

/* ******************************************************************** */

