/******************************************************************************
 *
 * Copyright (c) 1999	TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 *  
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 *	ImageListView.cpp
 *
 *****************************************************************************/

// SOL++2000
// 2000.02.18


#include <sol\ApplicationView.h>
#include <sol\PaintDC.h>
#include <sol\Static.h>
#include <sol\ImageList.h>


class ImageListView :public ApplicationView {
	int			toppos;
	int			spacing;
	int			extent;
	int			draggingId;
	ImageList* imglist;
	BOOL		dragging;
	Static		dropArea;
	long	size(Event& event);
	long 	paint(Event& event);
	long	leftButtonDown(Event& event);
	long	leftButtonUp(Event& event);
	long	mouseMove(Event& event);

	POINT	getCursorPosInWindow();
  public:
	ImageListView(Application& applet, const char* label, Args& args);
	~ImageListView();
};


long ImageListView::size(Event& event) 
{
	LPARAM l = event.getLParam();
	dropArea.reshape(2, 100, 100, 100); 
	return 0;
}

long ImageListView::paint(Event& event)
{
	PaintDC pdc(this);
	int num = imglist->getImageCount();

	for(int i = 0; i<num; i++) {
	 	imglist -> draw(i, &pdc, spacing*i, toppos, ILD_TRANSPARENT);
	}
	return NULL;
}


long ImageListView::leftButtonDown(Event& event) 
{
	POINT pt;
	LPARAM l = event.getLParam();
	pt.x = LOWORD(l);
	pt.y = HIWORD(l);

	draggingId = -1;
	int num = imglist->getImageCount();

	for(int i = 0; i<num; i++) {
		RECT rc;
		rc.left = spacing*i;
		rc.top  = toppos;
		rc.right = rc.left+extent;
		rc.bottom = rc.top+extent;
		POINT px = pt;
		if(PtInRect(&rc, px) && dragging == FALSE) {
			dragging = TRUE;
			POINT hotSpot;
			hotSpot.x = (pt.x-rc.left);
			hotSpot.y = (pt.y-rc.top);
			imglist->beginDrag(i, hotSpot.x,hotSpot.y);

			showCursor(FALSE);
			capture();
		
			POINT xx = getCursorPosInWindow();
			imglist->dragEnter(this, xx.x, xx.y);
			dragging = TRUE;
			draggingId = i;
			break;
	  	}
	}
	return 0;
}


long ImageListView::leftButtonUp(Event& event) 
{
	if(dragging) {
		dragging = FALSE;
		releaseCapture();
		imglist->endDrag();
		showCursor(TRUE);
		POINT pt;
		getCursorPos(&pt);
		toClient(&pt);
		HWND child = childWindowFromPoint(pt);
		if(dropArea.isEqual(child)) {
			HICON hIcon = imglist->getIcon(draggingId,ILD_TRANSPARENT); 
			dropArea.setIcon(hIcon);
			dropArea.reshape(2, 100, 100, 100);
		}
		else {
			MessageBeep(MB_ICONHAND);
		}
	}
	return 0;
}

long ImageListView::mouseMove(Event& event) 
{
	if(dragging) {
		POINT pt = getCursorPosInWindow();
		imglist->dragMove(pt.x, pt.y);
	}
	return 0;
}

POINT ImageListView::getCursorPosInWindow()
{
	POINT pt;
	getCursorPos(&pt);
	RECT r;
	getWindowRect(&r);
	pt.x -= r.left;
	pt.y -= r.top;
	return pt;
}


ImageListView::ImageListView(Application& applet, const char* label, Args& args)
	:ApplicationView(applet, label, args)
{
	toppos = 20;
	spacing = 50;
	extent    = 32;
	imglist = new ImageList(extent, extent, TRUE, 5, 1);
	imglist -> addIcon(LoadIcon(NULL,IDI_APPLICATION));
	imglist -> addIcon(LoadIcon(NULL,IDI_ASTERISK));
	imglist -> addIcon(LoadIcon(NULL,IDI_EXCLAMATION));
	imglist -> addIcon(LoadIcon(NULL,IDI_HAND));
	imglist -> addIcon(LoadIcon(NULL,IDI_QUESTION));

  	dragging = FALSE;

	Args ar;
	ar.set(XmNexStyle, (ulong)WS_EX_CLIENTEDGE);
	ar.set(XmNstyle, (ulong)WS_BORDER|SS_ICON);
	dropArea.create(this, "", ar);

	addEventHandler(WM_LBUTTONDOWN, this, 
		(Handler)&ImageListView::leftButtonDown, NULL);

	addEventHandler(WM_LBUTTONUP, this, 
		(Handler)&ImageListView::leftButtonUp, NULL);

	addEventHandler(WM_MOUSEMOVE, this, 
		(Handler)&ImageListView::mouseMove, NULL);

	addEventHandler(WM_PAINT, this, 
		(Handler)&ImageListView::paint, NULL);
}

ImageListView::~ImageListView()
{
	delete imglist;
}

//
void	Main(int argc, char** argv)
{
	const char* name = "ImageList";
	Application applet(name, argc, argv);

	Args args;
	ImageListView imageListView(applet, name, args);
	imageListView.realize();

	applet.run();
}

