#include <fstream>
#include <iostream>
#include <string>

using namespace std;

//-------------------------------------------
class NizBajtova
{
public:
	void Citaj( istream& udat )
		{}
		
	void Pisi( ostream& idat ) const
		{}
};

//-------------------------------------------
class SlozenaTransformacija
{
public:
	void Kodiranje( const NizBajtova& u, NizBajtova& i ) const
		{ 
		i = u; 
		}

	void Dekodiranje( const NizBajtova& u, NizBajtova& i ) const
		{ 
		i = u; 
		}
};

//-------------------------------------------
class ProgramKodDekod
{
public:
	void Priprema( int argc, char** argv )
		{
		if( argc < 4 )
			throw string("Upotreba: prg <u.dat> <i.dat> <nacin kodiranja>");
		
		_NazivUlazneDatoteke = argv[1];
		_NazivIzlazneDatoteke = argv[2];
		
		//_Transformacija = ...
		}
		
	void Obrada() const
		{
		ifstream udat( _NazivUlazneDatoteke.c_str(), ios::binary );
		if( !udat )
			throw string( "Nije uspelo otvaranje ulazne datoteke!" );
		ofstream idat( _NazivIzlazneDatoteke.c_str(), ios::binary );
		if( !idat )
			throw string( "Nije uspelo otvaranje izlazne datoteke!" );

		NizBajtova ulaz, izlaz;
		ulaz.Citaj( udat );
		Operacija( ulaz, izlaz );
		izlaz.Pisi( idat );		
		}
		
protected:
	virtual void Operacija( const NizBajtova& u, NizBajtova& i ) const = 0;
	SlozenaTransformacija	_Transformacija;
		
private:
	string 					_NazivUlazneDatoteke;
	string 					_NazivIzlazneDatoteke;
};

//-------------------------------------------
class ProgramKodiranje : public ProgramKodDekod
{
protected:
	void Operacija( const NizBajtova& u, NizBajtova& i ) const
		{ _Transformacija.Kodiranje( u, i ); }
};

//-------------------------------------------
class ProgramDekodiranje : public ProgramKodDekod
{
protected:
	void Operacija( const NizBajtova& u, NizBajtova& i ) const
		{ _Transformacija.Dekodiranje( u, i ); }
};

//-------------------------------------------
main( int argc, char** argv )
{
	try	{
		ProgramKodiranje p;
//		ProgramDekodiranje p;
		p.Priprema( argc, argv );
		p.Obrada();		
	} catch( string& s ){
		cerr << "GRESKA: " << s << endl;
	}
}


