#define STRICT
#define ORBITER_MODULE
#include <stdio.h>
#include "orbitersdk.h"
#include "ReleaseMeMFD.h"

// ==============================================================
// Global variables

int g_MFDmode; // identifier for new MFD mode

// ==============================================================
// API interface

DLLCLBK void InitModule (HINSTANCE hDLL)
{
	static char *name = "Release";
	MFDMODESPEC spec;
	spec.name = name;
	spec.key = OAPI_KEY_R;
	spec.msgproc = ReleaseMeMFD::MsgProc;

	// Register the new MFD mode with Orbiter
	g_MFDmode = oapiRegisterMFDMode (spec);
}

DLLCLBK void ExitModule (HINSTANCE hDLL)
{
	// Unregister the custom MFD mode when the module is unloaded
	oapiUnregisterMFDMode (g_MFDmode);
}

// ==============================================================
// MFD class implementation

// Constructor
ReleaseMeMFD::ReleaseMeMFD (DWORD w, DWORD h, VESSEL *vessel)
: MFD (w, h, vessel)
{
	this->vessel=vessel;
	this->object=vessel->GetHandle();
	this->width=(int)w/35;
	this->heigth=(int)h/28;
}

// Destructor
ReleaseMeMFD::~ReleaseMeMFD ()
{
	// Add MFD cleanup code here
}

// Return button labels
char *ReleaseMeMFD::ButtonLabel (int bt)
{
	// The labels for the two buttons used by our MFD mode
	static char *label[1] = {"REL"};
	return (bt < 1 ? label[bt] : 0);
}

// Return button menus
int ReleaseMeMFD::ButtonMenu (const MFDBUTTONMENU **menu) const
{
	// The menu descriptions for the two buttons
	static const MFDBUTTONMENU mnu[2] = {
		{"Release from parents", 0, 'D'}		
	};
	if (menu) *menu = mnu;
	return 1; // return the number of buttons used
}


// Repaint the MFD
void ReleaseMeMFD::Update (HDC hDC)
{
	ATTACHMENTHANDLE point;
	DWORD i, j=vessel->AttachmentCount(true);
	char buffer[20];
	strcpy(buffer, "F R E E");
	for(i=0;i<j;i++)
	{
		point=vessel->GetAttachmentHandle(true, i);
		if (point!=0)
			if (vessel->GetAttachmentStatus(point)!=0)
			{
				strcpy(buffer, "A T T A C H E D");
				break;
			}
	}
	int l=strlen(buffer);
	SelectDefaultFont (hDC, 0);
	SelectDefaultPen (hDC, 4);
	TextOut(hDC, (35-l)/2*this->width, 13*this->heigth, buffer, l);
}

// MFD message parser
int ReleaseMeMFD::MsgProc (UINT msg, UINT mfd, WPARAM wparam, LPARAM lparam)
{
	switch (msg) {
	case OAPI_MSG_MFD_OPENED:
		// Our new MFD mode has been selected, so we create the MFD and
		// return a pointer to it.
		return (int)(new ReleaseMeMFD (LOWORD(wparam), HIWORD(wparam), (VESSEL*)lparam));
	}
	return 0;
}

bool ReleaseMeMFD::ConsumeKeyBuffered(DWORD key)
{	
	switch(key)
	{
	case OAPI_KEY_D:
		ReleaseFromAllParents();
		return true;	
	default:
		return false;	
	}
}

bool ReleaseMeMFD::ConsumeButton(int bt, int event)
{	
	if (event==PANEL_MOUSE_LBPRESSED)
	{
		switch(bt)
		{
		case 0:
			return ConsumeKeyBuffered(OAPI_KEY_D);
		}
	}
	return false;
}

void ReleaseMeMFD::ReleaseFromAllParents()
{
	ATTACHMENTHANDLE point;
	OBJHANDLE parentObject;
	VESSEL *parent;
	DWORD i;
	DWORD j=vessel->AttachmentCount(true);	
	for(i=0;i<j;i++)
	{
		point=vessel->GetAttachmentHandle(true, i);
		parentObject=vessel->GetAttachmentStatus(point);
		if (parentObject!=0)
		{			
			parent=oapiGetVesselInterface(parentObject);
			if (parent!=0)
			{				
				ReleaseFromParent(parent);
			}
		}
	}
}

void ReleaseMeMFD::ReleaseFromParent(VESSEL *vessel)
{
	ATTACHMENTHANDLE point;	
	DWORD i;
	DWORD j=vessel->AttachmentCount(false);	
	for(i=0;i<j;i++)
	{
		point=vessel->GetAttachmentHandle(false, i);
		if (this->object==vessel->GetAttachmentStatus(point))
		{
			vessel->DetachChild(point);
		}
	}
}