#include "c4d_toolplugin.h"
#include "c4d_memory.h"
#include "c4d_basecontainer.h"
#include "c4d_basebitmap.h"
#include "c4d_file.h"
#include "c4d_general.h"
#include "c4d_gui.h"
#include "c4d_resource.h"
#include "lib_description.h"

Bool ToolData::InitTool(BaseDocument *doc, BaseContainer &data, BaseThread *bt)
{
	return TRUE;
}

void ToolData::FreeTool(BaseDocument *doc, BaseContainer &data)
{
}

Bool ToolData::DoCommand(ModelingCommandData &mdat)
{
	return -1;
}

void ToolData::InitDefaultSettings(BaseDocument *pDoc, BaseContainer &data)
{
}

const String ToolData::GetResourceSymbol()
{
	return String();
}

Bool ToolData::MouseInput(BaseDocument *doc, BaseContainer &data, BaseDraw *bd, EditorWindow *win, const BaseContainer &msg)
{
	return TRUE;
}

Bool ToolData::KeyboardInput(BaseDocument *doc, BaseContainer &data, BaseDraw *bd, EditorWindow *win, const BaseContainer &msg)
{
	return FALSE;
}

LONG ToolData::GetState(BaseDocument *doc)
{
	return CMD_ENABLED;
}

Bool ToolData::GetCursorInfo(BaseDocument *doc, BaseContainer &data, BaseDraw *bd, Real x,Real y, BaseContainer &bc)
{
	return FALSE;
}

TOOLDRAW ToolData::Draw(BaseDocument *doc, BaseContainer &data, BaseDraw *bd, BaseDrawHelp *bh, BaseThread *bt,TOOLDRAWFLAGS flags)
{
	return TOOLDRAW_AXIS;
}

CDialog* ToolData::AllocDialog(BaseContainer *bc, CDialog *cd_parent, LONG dlg_id)
{
  if (!cd_parent) return NULL;
  SubDialog* dlg = AllocSubDialog(bc);
  if (!dlg) return NULL;
  C4DOS.Cd->AttachSubDialog(cd_parent, dlg_id, dlg->Get());
  return dlg->Get();
}

void ToolData::FreeDialog(CDialog *cd)
{
  SubDialog *dlg = (SubDialog*)C4DOS.Cd->GetUserData(cd);
	gDelete(dlg);
}

Bool ToolData::InitDisplayControl(BaseDocument *doc, BaseContainer &data, BaseDraw *bd, const AtomArray *active)
{
	return FALSE;
}

void ToolData::FreeDisplayControl(void)
{
}

Bool ToolData::DisplayControl(BaseDocument *doc, BaseObject *op, BaseObject *chainstart, BaseDraw *bd, BaseDrawHelp *bh, ControlDisplayStruct &cds)
{
	return TRUE;
}

SubDialog* ToolData::AllocSubDialog(BaseContainer* bc)
{
	return NULL;
}

Bool ToolData::GetDDescription(BaseDocument *doc, BaseContainer &data, Description *description,DESCFLAGS_DESC &flags)
{
	return FALSE;
}

Bool ToolData::GetDParameter(BaseDocument *doc, BaseContainer &data, const DescID &id,GeData &t_data,DESCFLAGS_GET &flags)
{
	if (flags & DESCFLAGS_GET_PARAM_GET) return TRUE;
	return FALSE;
}

Bool ToolData::GetDEnabling(BaseDocument *doc, BaseContainer &data, const DescID &id,const GeData &t_data,DESCFLAGS_ENABLE flags,const BaseContainer *itemdesc)
{
	return TRUE;
}

Bool ToolData::SetDParameter(BaseDocument *doc, BaseContainer &data, const DescID &id,const GeData &t_data,DESCFLAGS_SET &flags)
{
	if (flags & DESCFLAGS_SET_PARAM_SET) return TRUE;
	return FALSE;
}

Bool ToolData::Message(BaseDocument *doc, BaseContainer &data, LONG type, void *t_data)
{
	return FALSE;
}

BaseContainer *GetToolData(BaseDocument *doc,LONG pluginid)
{
	return C4DOS.Ge->GetToolData(doc,pluginid);
}

Real GetToolScale(BaseDraw* bd, AtomArray* arr, Bool all, LONG mode)
{
	return C4DOS.Ge->GetToolScale(bd, arr, all, mode);
}

Bool RegisterToolPlugin(LONG id, const String &str, LONG info, String iconname, const String &help, ToolData *dat)
{
	if (!dat) return FALSE;

	Bool ok=FALSE;

	if (iconname.Content())
	{
		AutoAlloc<BaseBitmap> icon;
		if (icon && icon->Init(GeGetPluginPath()+String("res")+iconname)==IMAGERESULT_OK)
			ok=RegisterToolPlugin(id,str,info,icon,help,dat);
	}
	else
		ok=RegisterToolPlugin(id,str,info,NULL,help,dat);

	return ok;
}

Bool RegisterToolPlugin(LONG id, const String &str, LONG info, const String &help, ToolData *dat)
{
	return RegisterToolPlugin(id,str,info,NULL,help,dat);
}

Bool RegisterToolPlugin(LONG id, const String &str, LONG info, BaseBitmap *icon, const String &help, ToolData *dat)
{
	if (!dat) return FALSE;

	TOOLPLUGIN np;
	ClearMem(&np,sizeof(np));

	const String description = dat->GetResourceSymbol();

	if (description.Content() && !RegisterDescription(id,description)) return FALSE;

	np.adr								= dat;
	np.help								= (String*)&help;
	np.command_icon				= icon;
	np.info								= info;
												 
	np.Destructor					= &ToolData::Destructor;
	np.MouseInput					= &ToolData::MouseInput;
	np.KeyboardInput			= &ToolData::KeyboardInput;
	np.GetState						= &ToolData::GetState;
	np.GetCursorInfo			= &ToolData::GetCursorInfo;
	np.Draw								= &ToolData::Draw;
	np.AllocDialog				= &ToolData::AllocDialog;
	np.FreeDialog					= &ToolData::FreeDialog;
	np.InitTool						= &ToolData::InitTool;
	np.FreeTool						= &ToolData::FreeTool;
	np.InitDisplayControl = &ToolData::InitDisplayControl;
	np.FreeDisplayControl = &ToolData::FreeDisplayControl;
	np.DisplayControl			= &ToolData::DisplayControl;

	np.GetDDescription		= &ToolData::GetDDescription;
	np.GetDParameter			= &ToolData::GetDParameter;
	np.GetDEnabling				= &ToolData::GetDEnabling;
	np.SetDParameter			= &ToolData::SetDParameter;
	np.Message						= &ToolData::Message;
	np.InitDefaultSettings= &ToolData::InitDefaultSettings;
	np.DoCommand					= &ToolData::DoCommand;
	np.GetResourceSymbol  = &ToolData::GetResourceSymbol;

	return GeRegisterPlugin(PLUGINTYPE_TOOL,id,str,&np,sizeof(np));
}

void EditorWindow::DrawXORLine(LONG x1,LONG y1,LONG x2,LONG y2)
{
	C4DOS.Ge->EwDrawXORLine(this,x1,y1,x2,y2);
}

void EditorWindow::MouseDragStart(LONG button,Real mx,Real my,MOUSEDRAGFLAGS flag)
{
	C4DOS.Ge->EwMouseDragStart(this,button,mx,my,flag);
}

MOUSEDRAGRESULT EditorWindow::MouseDrag(Real *mx,Real *my,BaseContainer *channels)
{
	return C4DOS.Ge->EwMouseDrag(this,mx,my,channels);
}

MOUSEDRAGRESULT EditorWindow::MouseDragEnd(void)
{
	return C4DOS.Ge->EwMouseDragEnd(this);
}

Bool EditorWindow::BfGetInputState(LONG askdevice,LONG askchannel,BaseContainer *res)
{	
	return C4DOS.Ge->EwBfGetInputState(this,askdevice,askchannel,res);
}

Bool EditorWindow::BfGetInputEvent(LONG askdevice,BaseContainer *res)
{
	return C4DOS.Ge->EwBfGetInputEvent(this,askdevice,res);
}

Bool EditorWindow::IsHotkeyDown(LONG id)
{
	return C4DOS.Ge->EwBfIsHotkeyDown(this,id);
}

void EditorWindow::StatusSetText(const String &str)
{ 
	C4DOS.Ge->StatusSetText(&str); 
}

Bool EditorWindow::Screen2Local(LONG *x, LONG *y)
{
	return C4DOS.Ge->EWScreen2Local(this,x,y);
}

Bool EditorWindow::Local2Screen(LONG *x, LONG *y)
{
	return C4DOS.Ge->EWLocal2Screen(this,x,y);
}

Bool EditorWindow::Global2Local(LONG *x, LONG *y)
{
	return C4DOS.Ge->EWGlobal2Local(this,x,y);
}

Bool EditorWindow::Local2Global(LONG *x, LONG *y)
{
	return C4DOS.Ge->EWLocal2Global(this,x,y);
}

