/*
 *  MS Windows - dependent scene code
 */

#include <InterViews\itable.h>
#include <InterViews\bitmap.h>
#include <InterViews\canvas.h>
#include <InterViews\cursor.h>
#include <InterViews\interactor.h>
#include <InterViews\scene.h>
#include <InterViews\shape.h>
#include <InterViews\world.h>
#include <InterViews\X11\worldrep.h>
#include <InterViews\X11\windata.h>
#include <string.h>

static void DefaultShape (int w, int h, int& nw, int& nh) {
    nw = (w == 0) ? round(2*inch) : w;
    nh = (h == 0) ? round(2*inch) : h;
}

void Scene::UserPlace (Interactor* i, int w, int h) {
    int width, height;

    DefaultShape(w, h, width, height);
    MakeWindow(i, 0, 0, width, height);
    if (i->GetInteractorType()  == IconInteractor) {
	Assign(i, 0, 0, width, height);
    } else {
        DoMap(i, width, height);
    }
}

void Scene::Place (Interactor* i, Coord l, Coord b, Coord r, Coord t, boolean map) {
    Coord newtop = ymax - t;
    int width, height;

    DefaultShape(r - l + 1, t - b + 1, width, height);
    MakeWindow(i, l, newtop, width, height);
    Assign(i, l, b, width, height);
    if (map && i->GetInteractorType() != IconInteractor) {
	if (i->GetStartIconic() == false) {
	    Map(i);
	} else {
	    Interactor* icon_ia = i->GetIconInteractor();
	    if (icon_ia != nil) {
	        Canvas* dummy_canvas = nil;
		Canvas*& icon_canvas = icon_ia ? icon_ia->canvas : dummy_canvas;
		i->PlaceIcon(icon_ia, icon_canvas);
		Canvas* c;
	        if ((c = icon_ia->canvas) != nil) {
	            ShowWindow((HWND)c->id, SW_SHOW);
	        }
            }
        }
    }
}

void Scene::MakeWindow (Interactor* i, Coord x, Coord y, int width, int height) {
    HWND hWndParent;

    InteractorType t = i->GetInteractorType();
    hWndParent = (HWND)canvas->id;
    if (parent == nil) {
	hWndParent = NULL;
	if (t == InteriorInteractor) {
	    i->SetInteractorType(ToplevelInteractor);
	}
    } else if (t != InteriorInteractor) {
	i->SetInteractorType(InteriorInteractor);
    }

    int newy = y;
    int newwidth = width;
    int newheight = height;

    t = i->GetInteractorType();
    if ((t == ApplicationInteractor) || (t == ToplevelInteractor)) {
        if (newy - _world->YCaption >= 0) {
	    newy -= _world->YCaption;
        }
	newwidth += _world->XBorder*2;
	newheight += _world->YBorder*2 + _world->YCaption;
    }

    if (i->canvas == nil) {
	LPSTR  lpclassname  = (LPSTR)i->rep->GetWndClass();
	LPSTR  lpwindowname = (LPSTR)i->rep->GetWndName();
	DWORD  dwStyle =  i->rep->GetWndStyle();

	HWND hWnd = CreateWindow(
			lpclassname,
			lpwindowname,
			dwStyle,
			x,
			newy,
			newwidth,
			newheight,
			hWndParent,
			NULL,
			_world->hinstance(),
			NULL
		    );

	i->canvas = new Canvas((void*)hWnd);
	_world->itable()->Insert((void*)hWnd, i);

    } else {
	MoveWindow(
	    (HWND)i->canvas->id, x, newy, newwidth, newheight, TRUE
	);
    }
    i->Listen(i->cursensor == nil ? i->input : i->cursensor);
}

void Scene::Map (Interactor* i, boolean raised) {
    HWND hWnd = (HWND)i->canvas->id;
    if (!IsWindowVisible(hWnd)) {
	ShowWindow (hWnd, SW_SHOW);
    }
    if (raised) {
	BringWindowToTop (hWnd);
    }
    i->canvas->status = CanvasMapped;
}

void Scene::Unmap (Interactor* i) {
    HWND hWnd = (HWND)i->canvas->id;
    ShowWindow(hWnd, SW_HIDE);
    i->canvas->status = CanvasUnmapped;

/*    if (parent == nil && i->GetInteractorType() != PopupInteractor) {
	MSG msg;
	msg.hWnd = GetWorld()->Rep()->root();
	msg.message = WM_CLOSEWINDOW;
	SendMessage (msg.hWnd, msg.message, msg.wParam, msg.lParam);
    }
    ??   -) Sendmessage wartet bis bearbeitet
	 -) Absicht nicht klar
*/
}

void Scene::Raise (Interactor* i) {
    HWND hwnd = (HWND)i->canvas->id;
    DoRaise(i);
    BringWindowToTop (hwnd);
}

void Scene::Lower (Interactor* i) {
    DoLower(i);
}

void Scene::Move (Interactor* i, Coord x, Coord y, Alignment a) {
    Coord ax = x, ay = y;
    DoAlign(i, a, ax, ay);
    i->left = ax;
    i->bottom = ay;
    DoMove(i, ax, ay);
    if ((i->GetInteractorType() == ToplevelInteractor) ||
	(i->GetInteractorType() == ApplicationInteractor)) {
	MoveWindow (
		(HWND)i->canvas->id,
		 ax,
		 ymax - ay - i->ymax - _world->YCaption,
		 i->canvas->width + _world->XBorder*2,
		 i->canvas->height + _world->YBorder*2 + _world->YCaption,
		 TRUE
	);
    } else {
	MoveWindow (
		(HWND)i->canvas->id,
		 ax,
		 ymax - ay - i->ymax,
		 i->canvas->width,
		 i->canvas->height,
		 TRUE
	);

    }
}

void Scene::DoMap (Interactor* i, int w, int h) {
    HWND hWnd = (HWND)i->canvas->id;
    if (!IsWindowVisible(hWnd)) {
	ShowWindow (hWnd, SW_SHOW);
    }
    BringWindowToTop (hWnd);
    Assign(i, 0, 0, w, h);
    i->canvas->status = CanvasMapped;
}