#pragma once
#ifndef HIGHLIGHTER_H
#define HIGHLIGHTER_H

#include "XMLLexer.h"

#include <string>
#include <vector>
#include <map>
#include <iostream>

class Highlighter {
    public:
        /**
         * Create a new Highlighter with the content of the xml file
         */

        Highlighter(std::istream &file);
        virtual ~Highlighter();
        
        /**
         * Do the actual highlighting and write it to the provided ostream
         * This is a pure virtual function and has to be implemented when creating a new kind of highlighter
         */

        virtual void highlight(std::ostream &os)=0;

    protected:
       
        /**
        * Do the actual work with the lexer
        */ 

        void process();
        
        /**
         * Local Tokentype used to identify what part of the xml structure is inside the token
         * This is necessary because we use two different lexers with different TokenTypes
         */

        enum TokenType {
            COMMENT,
            TAG,
            CONTENT,
            ELEMENT,
            ATTRIBUTE,
            ATTRIBURE_CONTENT,
            WHITESPACE,
            BRACKET,
            nonmatching
        };
        
        /**
         * Represent all the different colors
         */

        enum Color { Red, Green, Blue, Orange, Yellow, Cyan, Grey, Black, White, Magenta, Pink, Brown, Indigo, Violet, Undefined}; // All the colors, not all of them are used, but it's easy to change now
    
        /**
         * A structure used to hold the tokens with their content, TokenType and color
         */

        struct Token {
            std::string content = "";
            Color color;
            TokenType type;
        };

        // Used to determine the color connected to the TokenType
        std::map<TokenType, Color> colormap;
        // Hold the tokens
        std::vector<Token> m_tokens;
        // Hold the first lexer
        XMLLexer *m_lexer;
};

class ConsoleHighlighter: public Highlighter {
    
    /**
     * A SyntaxHighlighter specifically for console output
     * Look at the base class for more information
     */

    public:
        ConsoleHighlighter(std::istream &file);
        void highlight(std::ostream &os);

};

#endif // HIGHLIGHTER_H
