// Name:        utils
// Purpose:     wxBugTracker
// Author:      Aleksandras Gluchovas (mailto:alex@soften.ktu.lt)
// Modified by:
// Created:     20/10/1999
// RCS-ID:      $Id: myutils.cpp,v 1.7 2001/03/06 01:25:29 aleksandras Exp $
// Copyright:   (c) Aleksandras Gluchovas
// Licence:   	GPL (version 2.0 or later)
/////////////////////////////////////////////////////////////////////////////

#ifdef __GNUG__
    #pragma implementation "myutils.cpp"
    #pragma interface "myutils.h"
#endif

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif

#include "myutils.h"
#include <stdlib.h>
#include <stdio.h>

// global helper-functions

wxString IntToStr( int i )
{
	char buf[32];
	sprintf( buf, "%d", i );

	return buf;
}

int StrToInt( const wxString& str )
{
	return atoi( (const char*)str );
}

wxString LoadFileContent( const wxString& fname, bool binary )
{
	wxString text = "";

	char buf[ 4096*8 ];
	memset( buf, 0, sizeof(buf) );

	int n = 0;

	FILE* f = NULL;
	
	if ( binary )

		f = fopen( fname, "rb" );
	else
		f = fopen( fname, "rt" );

	if ( f == NULL ) 
	{
		// create an empty file if does not exit yet

		f = fopen( fname, "wt" );
		char* s = "\n";
		fwrite( s, sizeof(char), 1, f );
		fclose( f );

		return s;
	}

	while( !feof( f ) )
	{
		int nRead = fread( buf, sizeof(char), sizeof(buf), f );

		text.append( buf, 0, nRead );
	}

	fclose( f );

	return text;
}

bool WriteFileContent( const wxString& fname, const wxString& content )
{
	FILE* f = fopen( fname, "w+t" );

	if ( f == NULL ) return FALSE;

	fwrite( (const char*)content, sizeof(char), content.length(), f );

	fclose(f);

	return TRUE;
}

bool AppendFileContent( const wxString& fname, const wxString& content )
{
	FILE* f = fopen( fname, "a+t" );

	if ( f == NULL ) return FALSE;

	fwrite( (const char*)content, sizeof(char), content.length(), f );

	fclose(f);

	return TRUE;
}

void ExtractConcatenatedValues( const wxString& str, 
							    StrListT& toList, 
								char separator )
{
	size_t i = 0, len = str.length();

	while( i < len )
	{
		size_t start = i;

		while( i < len && str[i] != separator ) ++i;

		toList.Add( wxString( str, start, i - start ) );

		++i; // skip separator
	}
}

void ExtractConcatenatedValues( const wxString& str, wxStringList& toList, char separator )
{
	size_t i = 0, len = str.length();

	while( i < len )
	{
		size_t start = i;

		while( i < len && str[i] != separator ) ++i;

		toList.Add( wxString( str, start, i - start ) );

		++i; // skip separator
	}
}

wxString ConcatenateValues( const StrListT& srcList, 
					      char separator )
{
	wxString result;

    size_t i;
	for( i = 0; i != (unsigned int)srcList.Count(); ++i )
	{
		if ( i != 0 ) result += separator;

		result += srcList[i];
	}

	return result;
}

bool is_forbidden_html_tag( const wxString& txt, size_t at )
{
	size_t len = txt.Length();
	const char* cur = txt;
	cur += at;
	++cur;

	while( *cur && *cur == ' ' && *cur == 10 && 
		   *cur == 13 && *cur == '\t' && *cur == '/')
		++cur;

	// FIXME:: dirty&crappy!

	if ( memcmp( (void*)cur, "object", 6 ) == 0 )
		return TRUE;

	if ( memcmp( (void*)cur, "table", 5 ) == 0 )
		return TRUE;

	if ( memcmp( (void*)cur, "td", 2 ) == 0 )
		return TRUE;

	if ( memcmp( (void*)cur, "tr", 2 ) == 0 )
		return TRUE;

	if ( memcmp( (void*)cur, "a", 1 ) == 0 )
		return TRUE;

	if ( memcmp( (void*)cur, "frameset", 7 ) == 0 )
		return TRUE;

	if ( memcmp( (void*)cur, "frame", 5 ) == 0 )
		return TRUE;

	return FALSE;
}

void skip_forbidden_html_tag( const wxString& txt, size_t& at )
{
	size_t len = txt.Length();

	while( at < len && txt[at] != '>' ) ++at;

	if ( at + 1 < len ) ++at; // skip '>'
}

wxString GetEscapedString( const wxString& src )
{
	wxString dest; size_t len = src.Length();

	for( size_t i = 0; i != len; ++i )
	{
		char ch = src[i];

		if ( ch == '<' && is_forbidden_html_tag( src, i ) )
		{
			skip_forbidden_html_tag( src, i );

			--i;
			continue;
		}

		if ( ch == '[' || 
			 ch == ']' ||
			 ch == '\"'||
			 ch == '\\' ) 

			 dest += '\\';

		dest += ch;
	}

	return dest;
}

wxString GetUnescapedString( const wxString& src )
{
	wxString dest; size_t len = src.Length();

	for( size_t i = 0; i < len; ++i )
	{
		char ch = src[i];
	
		if ( ch == '\\' )
		{
			if ( i + 1 < len )
			{
				++i;
				dest += src[i];
			}
		}
		else
			dest += ch;
	}

	return dest;
}

wxString RGBIntToStr( int rgb )
{
	int b = rgb & 0xFF;
	int g = ( rgb >> 8 )  & 0xFF;
	int r = ( rgb >> 16 ) & 0xFF;

	char buf[10];

	sprintf( buf, "#%.2X%.2X%.2X", r,g,b );

	return buf;
}

int StrToRGbInt( const wxString& str )
{
	int rgb = 0;

	if ( !str.Length() )
		return 0;

	if ( str[0] == '#' )

		sscanf( (const char*)str, "#%X", &rgb );
	else
		sscanf( (const char*)str, "%X", &rgb );

	return rgb;
}

int GetIntRedValue( int rgb )
{
	return ( rgb >> 16 ) & 0xFF;
}

int GetIntBlueValue( int rgb )
{
	return rgb & 0xFF;
}

int GetIntGreenValue( int rgb )
{
	return ( rgb >> 8 )  & 0xFF;
}

int MakeRGBInt( int r, int g, int b )
{
	return b | 
		   ( ( g << 8  ) & 0x00FF00 ) |
		   ( ( r << 16 ) & 0xFF0000 );
}

void ConcatString( wxString& toStr, const char* what, size_t len )
{
	char* str = (char*)what;
	char tmp = what[len];
	str[len] = '\0'; // terminate temporarely

	toStr += wxString( what, len );

	str[len] = tmp;
}

void StrListToStringList( wxStringList& dest, StrListT& src )
{
	dest.Clear();

    size_t i;
	for( i = 0; i != (unsigned int)src.Count(); ++i )

		dest.Add( src[i] );
}

#ifdef __WINDOWS__
	#include <windows.h> // file-time functions
	#include <io.h>
	#include <fcntl.h>
#endif

bool CompareMofidcationDates( const wxString& file1,
							  const wxString& file2,
							  int* result )
{
#ifdef __WINDOWS__

	HANDLE h1 = CreateFile( file1.c_str(), GENERIC_READ, 
					 	    FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES) NULL, 
							OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, 
							(HANDLE) NULL); 
 

	HANDLE h2 = CreateFile( file2.c_str(), GENERIC_READ, 
					 	    FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES) NULL, 
							OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, 
							(HANDLE) NULL); 

	//int fd1 = ::_open( file1.c_str(), GENERIC_READ,  0 );
	//int fd2 = ::_open( file2.c_str(), GENERIC_READ,  0 );

	if ( h1 == INVALID_HANDLE_VALUE ||
		 h2 == INVALID_HANDLE_VALUE )
	{
		if ( h1 != INVALID_HANDLE_VALUE ) ::CloseHandle( h1 );
		if ( h2 != INVALID_HANDLE_VALUE ) ::CloseHandle( h2 );

		return FALSE;
	}

	_FILETIME twr1, twr2;

	memset( &twr1, '\0', sizeof(_FILETIME) );
	memset( &twr2, '\0', sizeof(_FILETIME) );

	int ret2 = ::GetFileTime( h2, NULL, NULL, &twr2 );
	int ret1 = ::GetFileTime( h1, NULL, NULL, &twr1 );

	::CloseHandle( h1 );
	::CloseHandle( h2 );

	*result = ::CompareFileTime( &twr1, &twr2 );

	return TRUE;
#else
	*result = 0;

	return FALSE;
#endif 
}

static StrListT _gTmpStrings;

wxString& MakeTmpString( const wxString& str )
{
	_gTmpStrings.Add( str );

	return _gTmpStrings.Last();
}

void ClearTmpStrings()
{
	_gTmpStrings.Clear();
}

wxString ToPlatformText( const wxString& src )
{

#if defined(__WINDOWS__)
	wxString result = "";

	for( size_t i = 0; i != src.Length(); ++i )
	{
		if ( src[i] == '\n' )

			result += "\r\n";
		else
			result += src[i];
	}

	return result;
#else
	return src;
#endif

}
