// header file:   FileCoder.hpp
// description:   Concrete class with template methods for coding using a source and a target file.
//                Design patterns: Strategy. FileCoder is context, Coder is abstract strategy.
//                                 Facade hiding Coder, CoderFactory, FileI0.
//                Design scheme for bad cases: Action-query.
//                No getter for 'coder' since objects are immutable.
// variant:       2 with flexible composition
// author:        Karlheinz Hug
// creation date: 2012-07-05
// last update:   2012-08-06

#ifndef FILE_CODER_HPP_
#define FILE_CODER_HPP_

#include <string>
#include <vector>

#include "Coder.hpp"

	class FileCoder
	{
		public:
			FileCoder (Coder * const new_coder);
				// precondition: new_coder != 0

			virtual ~FileCoder ();

			virtual std::string coder_name () const;

			virtual void encode (const std::string & source_filename, const std::string & target_filename);
			virtual void decode (const std::string & source_filename, const std::string & target_filename);
				// 'encode' and 'decode' must be inverse to each other, i.e. for each 'a', 'b', 'c',
				// after 'encode(a, b); decode(b, c);', the contents of 'a' and 'c' must be equal.
				// Common preconditions for 'encode' and 'decode':
				// precondition: source_filename.size() > 0 && target_filename.size() > 0
				// precondition: source_filename != target_filename

			int result () const {return a_result;}

			static const int done          = 0;    // == FileIO::done == Coder::done
			static const int failed_open   = 1;    // == FileIO::failed_open
			static const int failed_write  = 2;    // == FileIO::failed_write
			static const int failed_decode = 11;   // == Coder::failed_decode
				// Values for result().

		protected:
			Coder * const coder;    // implementation invariant: coder != 0
			int           a_result;

			virtual void code
				(const std::string & source_filename, const std::string & target_filename,
				 void (Coder::*method) (const std::vector<char> &, std::vector<char> &));
				// precondition: source_filename.size() > 0 && target_filename.size() > 0
				// precondition: source_filename != target_filename
				// precondition: method != 0
				// 'method' is a member function pointer compatible with Coder::encode and Coder::decode.
	};

#endif // FILE_CODER_HPP_
