/*  Project leowl_1
	 xor@frognet.net
	 Copyright © 1996. Andrey B. Yastrebov. All Rights Reserved.

	 SUBSYSTEM:    leowl_1.exe Application
	 FILE:         leowl_1.cpp
	 AUTHOR:       Andrey B. Yastrebov


	 OVERVIEW
	 ========
	 Source file for implementation of leowl_1 (TApplication).
*/


#include <owl\owlpch.h>
#include <owl\statusba.h>
#include <owl\controlb.h>
#include <owl\buttonga.h>
#pragma hdrstop

#include <dir.h>

#include "leowl_1.h"
#include "leowl_1e.h"                        // Definition of client class.
#include "leowl_1z.h"                        // Definition of about dialog.

// Name of desktop file
const char DesktopFile[] = "LEOWL_1.DSK";

// Drag / Drop support:
TFileDrop::TFileDrop (char* fileName, TPoint& p, BOOL inClient, TModule*)
{
	 char    exePath[MAXPATH];

	 exePath[0] = 0;
	 FileName = strcpy(new char[strlen(fileName) + 1], fileName);
	 Point = p;
	 InClientArea = inClient;
}

TFileDrop::~TFileDrop ()
{
	 delete FileName;
}

const char *TFileDrop::WhoAmI ()
{
	 return FileName;
}

//{{leowl_1 Implementation}}

//
// Build a response table for all messages/commands handled
// by the application.
//
DEFINE_RESPONSE_TABLE1(leowl_1, TApplication)
//{{leowl_1RSP_TBL_BEGIN}}
	 EV_COMMAND(CM_HELPABOUT, CmHelpAbout),
	 EV_WM_DROPFILES,
	 EV_COMMAND(CM_DESKTOPRESTORE, CmDesktopRestore),
	 EV_COMMAND(CM_DESKTOPSAVE, CmDesktopSave),
//{{leowl_1RSP_TBL_END}}
END_RESPONSE_TABLE;

IMPLEMENT_STREAMABLE1(leowl_1,TApplication);
//////////////////////////////////////////////////////////
// leowl_1
// =======
//
leowl_1::leowl_1 () : TApplication("leowl_1")
{
}


leowl_1::~leowl_1 ()
{
}


//////////////////////////////////////////////////////////
// leowl_1
// =====
// Application intialization.
//
void leowl_1::InitMainWindow ()
{
	 if (nCmdShow != SW_HIDE)
		  nCmdShow = (nCmdShow != SW_SHOWMINNOACTIVE) ? SW_SHOWNORMAL : nCmdShow;

	 TDecoratedFrame *frame = new TDecoratedFrame(0, GetName(),
		new leowl_1Edit, TRUE);

	 //
	 // Assign ICON w/ this application.
	 //
	 frame->SetIcon(this, IDI_SDIAPPLICATION);

	 //
	 // Menu associated with window and accelerator table associated with table.
	 //
	 frame->AssignMenu(SDI_MENU);

	 //
	 // Associate with the accelerator table.
	 //
	 frame->Attr.AccelTable = SDI_MENU;

	 //
	 // Insert Control Bar
	 //
	 TControlBar* cb = new TControlBar(frame);
	 cb->Insert(*new TButtonGadget(CM_FILENEW, CM_FILENEW));
	 cb->Insert(*new TButtonGadget(CM_FILEOPEN, CM_FILEOPEN));
	 cb->Insert(*new TButtonGadget(CM_FILESAVE, CM_FILESAVE));
	 cb->Insert(*new TButtonGadget(CM_FILESAVEAS, CM_FILESAVEAS));
	 cb->Insert(*new TSeparatorGadget(6));
	 cb->Insert(*new TButtonGadget(CM_EDITCUT, CM_EDITCUT));
	 cb->Insert(*new TButtonGadget(CM_EDITCOPY, CM_EDITCOPY));
	 cb->Insert(*new TButtonGadget(CM_EDITPASTE, CM_EDITPASTE));
	 cb->Insert(*new TSeparatorGadget(6));
	 cb->Insert(*new TButtonGadget(CM_EDITUNDO, CM_EDITUNDO));
	 cb->Insert(*new TButtonGadget(CM_EDITREDO, CM_EDITREDO));
	 cb->Insert(*new TSeparatorGadget(6));
	 cb->Insert(*new TButtonGadget(CM_EDITFIND, CM_EDITFIND));
	 cb->Insert(*new TButtonGadget(CM_EDITREPLACE, CM_EDITREPLACE));
	 cb->Insert(*new TButtonGadget(CM_EDITFINDNEXT, CM_EDITFINDNEXT));

	 // Add fly-over help hints.
	 cb->SetHintMode(TGadgetWindow::EnterHints);

	 frame->Insert(*cb, TDecoratedFrame::Top);

	 //
	 // Insert Status Bar
	 //
	 TStatusBar* sb = new TStatusBar(frame, TGadget::Recessed,
		TStatusBar::CapsLock | TStatusBar::NumLock | TStatusBar::ScrollLock
		| TStatusBar::Overtype);
	 frame->Insert(*sb, TDecoratedFrame::Bottom);

	 SetMainWindow(frame);

	 frame->SetMenuDescr(TMenuDescr(SDI_MENU,1,2,1,0,0,1));
}

void leowl_1::OpenFile (const char *fileName)
{
	 leowl_1Edit *client = TYPESAFE_DOWNCAST(GetMainWindow()->GetClientWindow(),
		leowl_1Edit);     // Client window for the frame.
	 client->LoadFromFile(fileName);
    client->ReplaceAll("void","VoiD");
}

//////////////////////////////////////////////////////////
// leowl_1
// ===========
// Menu Help About leowl_1.exe command
void leowl_1::CmHelpAbout ()
{
	 //
	 // Show the modal dialog.
	 //
	 leowl_1z(MainWindow).Execute();
}


void leowl_1::InitInstance ()
{
	 TApplication::InitInstance();

	 //
	 // Attempt to load desktop from the stream.
	 //
    ifpstream is(DesktopFile);
	 if (!is.bad())
		{
        is.close();
		  CmDesktopRestore();
		}

	 // Accept files via drag/drop in the frame window.
	 GetMainWindow()->DragAcceptFiles(TRUE);

         if (_argc > 1)
            OpenFile(_argv[1]);

}

void leowl_1::EvDropFiles (TDropInfo drop)
{
	// Tell DragQueryFile the file interested in (0)
	// and the length of your buffer.
	int     fileLength = drop.DragQueryFileNameLen(0) + 1;
	char    *fileName = new char[fileLength];

	drop.DragQueryFile(0, fileName, fileLength);

	// Open the file that was dropped.
	OpenFile(fileName);

	// Release the memory allocated for this handle with DragFinish.
	drop.DragFinish();
}

void leowl_1::CmDesktopRestore ()
{
	 //
	 // Restore Desktop from the stream
	 //
	 ifpstream is(DesktopFile);
	 if (!is.bad())
		{
		  is >> *this;
		  is.close();
		}
}

void leowl_1::CmDesktopSave()
{
	 //
	 // Save Desktop into the stream
	 //
	 ofpstream os(DesktopFile);
	 if (!os.bad())
		{
		  os.flush();
		  os << *this;
		  os.close();
		}
}


BOOL leowl_1::CanClose ()
{
	 BOOL result = TApplication::CanClose();

	 //
	 // Must save desktop before closing
	 //
	 if (result)
		CmDesktopSave();

	 return result;
}

void *
leowl_1::Streamer::Read(ipstream& is, uint32) const
{
  leowl_1* Obj = GetObject();
  ReadBaseObject((TApplication*) Obj, is);
  TFrameWindow* fW = Obj->GetMainWindow();
  int X,Y,W,H;
  is >> X;
  is >> Y;
  is >> W;
  is >> H;
  TWindow* cW = fW->GetClientWindow();
  is >> *cW;
  fW->MoveWindow(X,Y,W,H,TRUE);
  return Obj;
}

void
leowl_1::Streamer::Write(opstream& os) const
{
  leowl_1* Obj = GetObject();
  WriteBaseObject((TApplication*) Obj, os);
  TFrameWindow* fW = Obj->GetMainWindow();
  os << fW->Attr.X;
  os << fW->Attr.Y;
  os << fW->Attr.W;
  os << fW->Attr.H;
  TWindow* cW = fW->GetClientWindow();
  os << *cW;
}


//
// Main procedure
//
int OwlMain (int , char* [])
{
	 try {
		  leowl_1    app;
		  return app.Run();
	 }
	 catch (xmsg& x) {
		  ::MessageBox(0, x.why().c_str(), "Exception", MB_OK);
	 }

	 return -1;
}
