#include <iostream>
#include <cstdlib>
#include "counting.h"
#include "seqinfileenumerator.h"

using namespace std;

struct Pair{
    char character;
    int number;

    friend ostream& operator<<(ostream&,const Pair&);
};

ostream& operator<<(ostream &os,const Pair &pair){
    os<<'#'<<pair.character<<pair.number;

    return os;
}

class Copying:public Summation<Pair,ofstream>{
    private:
        void Add(const Pair &pair){
            if(pair.number>1)
                *result<<pair;
            else
                *result<<pair.character;;
        }
    public:
        Copying(ofstream *outfile):Summation<Pair,ofstream>(outfile){}
};

class CharacterCounting:public Counting<char>{
    private:
        char character;
        void First(){}
        bool WhileCond(const char &ch) const{
            return ch==character;
        }
    public:
        CharacterCounting(const char &ch):Counting<char>(),character(ch){}
};

class PairEnumerator:public Enumerator<Pair>{
    private:
        SeqInFileEnumerator<char> *enor;
        Pair current;
        bool end;
    public:
        PairEnumerator(const string &str){
            try{
                enor=new SeqInFileEnumerator<char>(str);
            }catch(SeqInFileEnumerator<char>::Exceptions){
                exit(1);
            }
        }
        ~PairEnumerator(){
            delete enor;
        }
        void First(){
            enor->First();
            Next();
        }
        void Next();
        Pair Current() const{return current;}
        bool End() const{return end;}
};
void PairEnumerator::Next(){
    end=enor->End();
    if(!end){
        current.character=enor->Current();
        CharacterCounting cc(enor->Current());
        cc.AddEnumerator(enor);

        cc.Run();

        current.number=cc.Answer();
    }
}

int main(int argc,char** argv,char** envp){
	ofstream kimenet("output.txt");
	Copying copy(&kimenet);
	PairEnumerator *enor=new PairEnumerator("input.txt");
	copy.AddEnumerator(enor);

	copy.Run();

	delete enor;

    return 0;
}
