/*
 * Copyright (c) 2003, Frank Richter <frichter@gmx.li>
 * Copyright (c) 2003, Robert Collins <rbtcollins@hotmail.com>
 * Copyright (c) 2005-2006, Tom N Harris <telliamed@whoopdedo.org>
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Frank Richter.
 *
 */

#include "ControlAdjuster.h"

using namespace Setup;

void ControlAdjuster::AdjustControls(HWND dlg, const ControlInfo controlInfo[],   
				     int widthChange, int heightChange)
{
	const ControlInfo* ci = controlInfo;

	while (ci->control > 0)
	{
		ci->adjust(dlg, widthChange, heightChange);
		ci++;
	}
}

void
ControlAdjuster::ControlInfo::adjust(HWND dlg, int widthChange, int heightChange) const
{    
	HWND ctl = ::GetDlgItem(dlg, control);  
	if (ctl == 0)
		return;
	RECTWrapper ctlRect;
	::GetWindowRect(ctl, &ctlRect);
	// We want client coords.
	::ScreenToClient(dlg, (LPPOINT)&ctlRect.left);
	::ScreenToClient(dlg, (LPPOINT)&ctlRect.right);

	ControlDimension horizontal(ctlRect.left, ctlRect.right);
	ControlDimension vertical(ctlRect.top, ctlRect.bottom);
	/*
	  Now adjust the rectangle coordinates.
	*/
	adjust(horizontalPos, horizontal, widthChange);
	adjust(verticalPos, vertical, heightChange);
	/* update the windows window */
	::SetWindowPos(ctl, 0, ctlRect.left, ctlRect.top, 
			ctlRect.width(), ctlRect.height(), 
			SWP_NOACTIVATE | SWP_NOZORDER);
	// If not done, weird visual glitches can occur.
	::InvalidateRect(ctl, 0, false);
}
 
void
ControlAdjuster::ControlInfo::adjust(ControlPosition const& how, ControlDimension& where, int by) const
{
	switch (how)
	{
	  case CP_LEFT:
		break;
	  case CP_CENTER:
		where.left += by/2;
		where.right += by/2;
		break;
	  case CP_RIGHT:
		where.left += by;
		where.right += by;
		break;
	  case CP_STRETCH:
		where.right += by;
		break;
	}
}
 
SizeProcessor::SizeProcessor()
	: m_rectValid(false)
{
}
 
void SizeProcessor::addControlInfo(const ControlAdjuster::ControlInfo* controlInfo)
{
	m_controlInfos.push_back(controlInfo);
}

void SizeProcessor::updateSize(HWND dlg)
{
	RECTWrapper clientRect;
	::GetClientRect(dlg, &clientRect);

	if (m_rectValid)
	{
		const int dX = clientRect.width() - m_lastRect.width();
		const int dY = clientRect.height() - m_lastRect.height();
		
		ControlInfoList::iterator i;
		for (i = m_controlInfos.begin(); i != m_controlInfos.end(); ++i)
			ControlAdjuster::AdjustControls(dlg, *i, dX, dY);
	}
	else
		m_rectValid = true;

	m_lastRect = clientRect;
}
