/******************************************************************************
 *
 * 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.
 *
 *
 *	Label.cpp
 *
 *****************************************************************************/

// SOL++2000

#include <sol\BitmapFile.h>
#include <sol\Label.h>
#include <sol\Bitmap.h>
#include <sol\Icon.h>
#include <sol\PaintDC.h>
#include <sol\ClientDC.h>
#include <shellapi.h>


Label::Label(View* parent, const char* name, Args& args)
	:Primitive(parent, name,
		args.set(XmNstyle, (ulong)WS_GROUP)
		    .set(XmNbackground, (COLOR_BTNFACE+1))
		    .set(XmNclassName, "Label")
			.set(XmNclassStyle, (ulong)CS_VREDRAW|CS_HREDRAW))
{
	addEventHandler(WM_PAINT, this,
			(Handler)&Label::paint, NULL);
	addEventHandler(WM_SIZE, this,
			(Handler)&Label::size, NULL);
	resource      = NULL;
	recomputeSize = TRUE;
	setValues(args);
}


Boolean Label::create(View* parent, const char* name, Args& args)
{
	Boolean rc = Primitive::create(parent, name,
		args.set(XmNstyle, (ulong)WS_GROUP)
		    .set(XmNbackground, (COLOR_BTNFACE+1))
		    .set(XmNclassName, "Label")
			.set(XmNclassStyle, (ulong)CS_VREDRAW|CS_HREDRAW));

	addEventHandler(WM_PAINT, this,
			(Handler)&Label::paint, NULL);
	addEventHandler(WM_SIZE, this,
			(Handler)&Label::size, NULL);
	resource      = NULL;
	recomputeSize = TRUE;
	setValues(args);

	return rc;
}


void Label::getValues(Args& args)
{
	Primitive::getValues(args);

	int num   = args.getCount();
	Arg* arg  = args.getArgList();

	for (int j = 0; j<num; j++) {
		const char*   name  = arg[j].name;
		ulong* val  = (ulong*)arg[j].value;
		if(name == XmNrecomputeSize) {
			*val = recomputeSize;
			continue;
		}
		if(name == XmNlabelType) {
			*val = labelType;
			continue;
		}
	}
}


void Label::setValues(Args& args)
{
	Primitive::setValues(args);

	char  label[256];
	getText(label, 256);
	labelType = (int) args.get(XmNlabelType);
	HICON   hicon   = (HICON)  args.get(XmNicon);
	HBITMAP hbitmap = (HBITMAP)args.get(XmNbitmap);

	if (labelType == LABEL_STRING) {
		ClientDC cdc(this);
		Size size;
		cdc.getTextExtent(label, strlen(label), &size);
		height = size.cy + 3;
		width  = size.cx + 3;
	}
	if (hicon) {
		labelType = LABEL_ICON;
		if(resource) delete resource;
		resource  = new Icon("", hicon);
		resource -> getSize(&width, &height);
	}
	if (hbitmap) {
		labelType = LABEL_BITMAP;
		if(resource) delete resource;
		resource  = new Bitmap(label, hbitmap);
		resource -> getSize(&width, &height);
	}
	if (hicon == NULL && hbitmap == NULL) {
		setLabel(label);
	}
	width++;
	height++;

	ulong val;
	if (args.get(XmNrecomputeSize, &val))
		recomputeSize = (BOOL)val;
	if (recomputeSize == TRUE) 
		send(WM_SIZE, 0, 0L);

	update(NULL);
}


long Label::size(Event& event)
{
	int x, y, w, h;

	getGeometry(x, y, w, h);
	if(recomputeSize == TRUE) 
		reshape(x, y, width, height);
	return NULL;
}


long Label::paint(Event& event)
{
	int x, y;
	int	w, h;

	PaintDC pdc(this);
	getGeometry(x, y, w, h);
	RECT rect;
	getWindowRect(&rect);
	HDC hdc = pdc.get();

	if(labelType == LABEL_STRING) {
		char	text[256];
		getText(text, 256);
		pdc.setBkMode(TRANSPARENT);
		Size size;
		DWORD ext = pdc.getTextExtent(text, strlen(text), &size);
		int hh = size.cy;	
		int ww = size.cx;	
		pdc.textOut(2, (h-hh)/2, text, strlen(text));
	}
	if(resource != NULL &&
	  (labelType == LABEL_BITMAP || 
	   labelType == LABEL_ICON) ) {
		resource -> draw(hdc, 0, 0);
	}
	return NULL;
}


void Label::setLabel(const char* label)
{
	ClientDC cdc(this);

	labelType = LABEL_STRING;

	ulong val;
	get(XmNinstance, &val);

	char* dot = strrchr((char*)label, '.');
	char ext[5];
	ext[0] = NULL;
	if(dot) strcpy(ext, dot);
	char* name = strrchr((char*)label, '\\');
	if(name) 
		name++;
	else
		name = (char*)label;

	if(strcmp(ext, ".ico") == 0) {
		HICON hicon = ::ExtractIcon((HINSTANCE)val, label, 0);
		if(hicon) {
			if(resource) delete resource;
			resource = new Icon("", hicon);
			labelType = LABEL_ICON;
			resource -> getSize(&width, &height);
		}
	}
	if(strcmp(ext, ".bmp") == 0) {
		BitmapFile bmpFile;
		if(bmpFile.openReadOnly(label) >= 0) {
			HBITMAP hbmp = bmpFile.extract(cdc.get());
			if(hbmp) {
				if(resource) delete resource;
				resource = new Bitmap(name, hbmp);
				labelType = LABEL_BITMAP;
				resource -> getSize(&width, &height);
			}
			bmpFile.close();
		}
	}
	if(labelType == LABEL_STRING) {
		Size size;
		cdc.getTextExtent(label, strlen(label), &size);
		height = size.cy + 4;
		width  = size.cx + 4;
	}
}

