/************************** * * * * * * * * * * * * ***************************
    Copyright (c) 1999-2005 Ryan Bobko
                       ryan@ostrich-emulators.com

    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.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     
*************************** * * * * * * * * * * * * **************************/

#ifndef _QHACCUTILS_H
#define _QHACCUTILS_H

#include "qhaccconstants.h"

#include <iostream>
using namespace std;

#include <qobject.h>

class QHacc;
class TableRow;

enum ConvertFlags { 
	PrefSep=0x1,
	AltSep=0x2,
	EngSep=0x4,
	HasSep=0x7,     // AltSep|PrefSep|EngSep
	PrefVal=0x8,
	Preference=0x9, // PrefSep|PrefVal
	AltVal=0x10,
	Alternate=0x12, // AltSep|AltVal
	EngVal=0x20,
	Engine=0x24,    // EngSep|EngVal
	HasVal=0x38     // PrefVal|AltVal|EngVal
};

class Utils {
 public:
	~Utils();

	static Utils * get();
	static void parser( const QString& str, const QString& sep, int start,
											QString * tokens, int numT );
	static bool debug( int, std::ostream *& );
	static bool error( int, std::ostream *& );
	static void setDebug( int );
	static int getDebug();

	static const int PRINT, ERRFATAL, ERROPER, ERRDEFAULT, DBGMAJOR,
		DBGMINOR, CURIOSITY;

	static QDate dateFromString( const QString& date, const QString& sep,
															 int form );
	static QString stringFromDate( const QDate& date, const QString& sep,
																 int form );
	static QString shortStringFromDate( const QDate& date, const QString& sep,
																			int form );

	/**
	 * @return the name of the given field
	 */
	static const char * tcname( Table t, int field );

	/**
	 * @return the type of the given field
	 */
	static ColType tctype( Table t, int field );

	/**
	 * @return the field number for the given string
	 */
	static int tcnum( Table t, const QString& name );
	
	/**
	 * @return the number of columns in the given table
	 */
	static int tcols( Table t );

	/**
	 * @return the primary key column for given table
	 */
	static int tpk( Table t );

	/**
	 * @return the field names of the given table
	 */
	static const char ** tnames( Table t );

	/**
	 * @return the types of the given table
	 */
	static const ColType * ttypes( Table t );

	/**
	 * @return true if the given account is a loan
	 */
	static bool isLoan( const TableRow&, float * interest =0, 
											QString * payment =0, int * numpays =0 );

	/**
	 * @return true if the given split is a market transaction
	 */
	static bool isMarket( const TableRow&, QString * shares =0, 
												QString * price =0 );
	/**
	 * Split the txt string into the number of shares and price for market trans
	 * The txt string is expected in the form "market(shares@price)," as
	 * will be passed from the Transaction Editor or Split Editor
	 * 
	 * @return true if the give string denotes a market transaction
	 */
	static bool isMarket( const QString& txt, QString& shares, QString& price );

 private:
	static const int COLS[];
	static const char ** NAMES[];
	static const ColType * TYPES[];
	static const int PKS[];
	
	static Utils * obj;
	static int QD;

	/* debug levels are:
	 *
	 * 0: no debugging nor errors
	 * 1: fatal errors only
	 * 2: errors that affect operation
	 * 3: errors requiring default values to be used
	 * 4: print major debugging information
	 * 5: print minor debugging information
	 * 6: for the curiosity cat
	 *
	 */
};

class MonCon {
 public:
	MonCon( QHacc * engine );
	~MonCon();

	/**
	 * Convert the given sum in the from format to the same value 
	 * converted to the to format
	 * @param currentval The sum to be converted
	 * @param from The current format of the value
	 * @param to The desired format of the value
	 * @return The converted sum
	 */
	QString convert( const QString& currentval, ConvertFlags from = Engine,
									 ConvertFlags to = Preference ) const;

	/**
	 * Essentially the same function as above
	 */
	QString convert( int currentval, ConvertFlags from = Engine,
									 ConvertFlags to = Preference ) const;

	/**
	 * Essentially like the above function, but returns an unmodified
	 * integer instead of a converted string
	 */
	int converti( const QString& currentval, ConvertFlags from = Engine,
								ConvertFlags to = Preference ) const;

	/**
	 * Essentially like the above function, but returns an unmodified
	 * integer instead of a converted string
	 */
	int converti( int currentval, ConvertFlags from = Engine,
								ConvertFlags to = Preference ) const;

	const QString& symbol() const;
	const QString& cursep() const;

	void changedP( const QString&, float );
	void changedP( const QString&, bool );
	void changedP( const QString&, QString );

 private:
	QHacc * engine;
	float factor;
	QString csymb, asymb, curs;
	static const QString ecurs;
	bool inAlt, prefUseESep, prefUseEVal;

	void decoder( ConvertFlags from, ConvertFlags to, 
								bool& fromenginesep, bool& fromengineval,
								bool& toenginesep, bool& toengineval ) const;

	QString converte( int currentval, ConvertFlags toflags ) const;
	int ci( int currentval, bool toeval ) const;
	static QString replace( QString, const QString& find,
													const QString& repl );
	static QString basic( int );
	static int basic( const QString& );
	void figurePrefs();


	MonCon( const MonCon& ); // no copies
	MonCon& operator=( const MonCon& ); // no assignments
};

#endif
