/*
 * Copyright (c) 2005-2006 Tom N Harris.
 *
 *     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 Tom N Harris <telliamed@whoopdedo.org>.
 *
 */

#include "FileVersion.h"

using namespace Setup;

FileVersion::FileVersion(String const& fname)
	: m_data(NULL), m_bufsize(0)
{
	memset(&m_time, 0, sizeof(m_time));
	memset(&m_info, 0, sizeof(m_info));
	m_info.dwFileFlags = VS_FF_INFOINFERRED;

	WIN32_FILE_ATTRIBUTE_DATA attr;
	if (!::GetFileAttributesEx(fname.c_str(), GetFileExInfoStandard, &attr))
		return;
	m_time = attr.ftLastWriteTime;

	DWORD h;
	m_bufsize = ::GetFileVersionInfoSize(const_cast<LPTSTR>(fname.c_str()), &h);
	if (m_bufsize != 0)
	{
		m_data = reinterpret_cast<BYTE*>(::operator new(m_bufsize));
		if (::GetFileVersionInfo(const_cast<LPTSTR>(fname.c_str()), 0, m_bufsize, m_data))
		{
			VS_FIXEDFILEINFO* pinfo;
			unsigned int datalen = 0;
			::VerQueryValue(m_data, const_cast<LPTSTR>(TEXT("\\")), (LPVOID*)(&pinfo), &datalen);
			if (datalen >= sizeof(m_info))
				m_info = *pinfo;
		}
	}
}

FileVersion::~FileVersion()
{
	::operator delete(m_data);
}


bool 
FileVersion::operator== (FileVersion const& other)
{
	if (m_info.dwFileFlags == VS_FF_INFOINFERRED
	 || other.m_info.dwFileFlags == VS_FF_INFOINFERRED)
	{
		return (m_time.dwHighDateTime == other.m_time.dwHighDateTime)
		    && (m_time.dwLowDateTime == other.m_time.dwLowDateTime);
	}
	return (m_info.dwFileVersionMS == other.m_info.dwFileVersionMS)
	    && (m_info.dwFileVersionLS == other.m_info.dwFileVersionLS);
}

bool 
FileVersion::operator< (FileVersion const& other)
{
	if (m_info.dwFileFlags == VS_FF_INFOINFERRED
	 || other.m_info.dwFileFlags == VS_FF_INFOINFERRED)
	{
		return (m_time.dwHighDateTime < other.m_time.dwHighDateTime)
		    || ((m_time.dwHighDateTime == other.m_time.dwHighDateTime)
		     && (m_time.dwLowDateTime < other.m_time.dwLowDateTime));
	}
	return (m_info.dwFileVersionMS < other.m_info.dwFileVersionMS)
	    || ((m_info.dwFileVersionMS == other.m_info.dwFileVersionMS)
	     && (m_info.dwFileVersionLS < other.m_info.dwFileVersionLS));
}

bool 
FileVersion::operator> (FileVersion const& other)
{
	if (m_info.dwFileFlags == VS_FF_INFOINFERRED
	 || other.m_info.dwFileFlags == VS_FF_INFOINFERRED)
	{
		return (m_time.dwHighDateTime > other.m_time.dwHighDateTime)
		    || ((m_time.dwHighDateTime == other.m_time.dwHighDateTime)
		     && (m_time.dwLowDateTime > other.m_time.dwLowDateTime));
	}
	return (m_info.dwFileVersionMS > other.m_info.dwFileVersionMS)
	    || ((m_info.dwFileVersionMS == other.m_info.dwFileVersionMS)
	     && (m_info.dwFileVersionLS > other.m_info.dwFileVersionLS));
}

