#ifndef __FDOC2HTML__
#define __FDOC2HTML__

#include "fdoc_parser.h"

template<class IteratorT>
class HtmlTocRenderer : public FDocParser<IteratorT>::Evaler {
  
  protected:
    typedef typename FDocParser<IteratorT>::ParserContext::item_t item_t;
    typedef typename item_t::const_iterator iterator_t;
    
    unsigned int header_index;
    unsigned int previous_level;
  
  public:
    HtmlTocRenderer() : header_index(0), previous_level(0) {}
    ~HtmlTocRenderer() {}
  
  
    void eval(const string &str){}
    
    void eval(const typename HtmlTocRenderer::ParserContext &context){
      eval_recursive(context);
    }
    
    //RootContext
    void eval(const typename HtmlTocRenderer::RootContext &context){
      
      eval_recursive(context);
      while(previous_level > 0){
        previous_level--;
        cout << "</li></ul>";
      }
    }
    
    //Header
    void eval(const typename HtmlTocRenderer::Header &context){
      
      if(previous_level < context.level()){
        while(previous_level < context.level()){
          previous_level++;
          cout << "<ul>";
        }
      }else{
        while(previous_level > context.level()){
          previous_level--;
          cout << "</li></ul>" << endl;
        }
        cout << "</li>";
      }
      
      cout << "<li>";
      cout << "<a href=\"#_header" << (header_index++) << "\">";
      cout << context.text();
      cout << "</a>" << endl;
    }
};

template<class IteratorT>
class HtmlRenderer : public FDocParser<IteratorT>::Evaler {
  
  protected:
    typedef typename FDocParser<IteratorT>::ParserContext::item_t item_t;
    typedef typename item_t::const_iterator iterator_t;
    
    unsigned int header_index;
  
  public:
    HtmlRenderer() : header_index(0) {}
    ~HtmlRenderer() {}
  
  
    void eval(const string &str){
      cout << str;
    }
    
    void eval(const typename HtmlRenderer::ParserContext &context){
      eval_recursive(context);
    }
    
    //AutoLinefeed
    void eval(const typename HtmlRenderer::AutoLinefeedContext &context){
      iterator_t it = context.begin();
      (*it)->eval(*this);
      bool previous_is_block((*it)->is_block());
      while(++it < context.end()){
        bool next_is_block((*it)->is_block());
        if(!next_is_block
            && !previous_is_block){cout << "<br />" << endl;}
        (*it)->eval(*this);
        previous_is_block = next_is_block;
      }
    }
    
    //Paragraph
    void eval(const typename HtmlRenderer::Paragraph &context){
      cout << "<p>";
      eval((typename HtmlRenderer::AutoLinefeedContext) context);
      //eval_recursive(context); //AutoLinefeedContext::eval(buf);
      cout << "</p>" << endl;
    }
    
    //Link
    void eval(const typename HtmlRenderer::Link &context){
      cout << "<a href=\"";
      //if(Link::is_FDocName(target)){buf.append("wiki.cgi?target=");}
      context[0]->eval(*this);
      cout << "\">";
      context[context.items() > 1 ? 1 : 0]->eval(*this);
      cout << "</a>";
    }
    
    //Strong
    void eval(const typename HtmlRenderer::Strong &context){
      cout << "<strong>";
      eval_recursive(context);
      cout << "</strong>";
    }
    
    //Del
    void eval(const typename HtmlRenderer::Del &context){
      cout << "<del>";
      eval_recursive(context);
      cout << "</del>";
    }
    
    //UnderLine
    void eval(const typename HtmlRenderer::UnderLine &context){
      cout << "<span style=\"text-decoration: underline;\">";
      eval_recursive(context);
      cout << "</span>";
    }
    
    //Header
    void eval(const typename HtmlRenderer::Header &context){
      
      cout << "<a name=\"_header" << (header_index++) << "\"></a>";
      cout << "<h" << context.level() << ">";
      eval_recursive(context);
      cout << "</h" << context.level() << ">" << endl;
    }
    
    //UList
    void eval(const typename HtmlRenderer::UList &context){
      cout << "<ul>" << endl;
      for(iterator_t it = context.begin(); it < context.end(); it++){
        cout << "<li>";
        (*it)->eval(*this);
        cout << "</li>" << endl;
      }
      cout << "</ul>" << endl;
    }
    
    //OList
    void eval(const typename HtmlRenderer::OList &context){
      cout << "<ol>" << endl;
      for(iterator_t it = context.begin(); it < context.end(); it++){
        cout << "<li>";
        (*it)->eval(*this);
        cout << "</li>" << endl;
      }
      cout << "</ol>" << endl;
    }
    
    //DList
    void eval(const typename HtmlRenderer::DList &context){
      cout << "<dl>" << endl;
      for(iterator_t it = context.begin(); it < context.end(); it++){
        cout << "<dt>";
        (*it)->eval(*this);
        cout << "</dt>" << endl;
        if(it++ == context.end()){cout << "<dd></dd>" << endl;}
        else{
          cout << "<dd>";
          (*it)->eval(*this);
          cout << "</dd>" << endl;
        }
      }
      cout << "</dl>" << endl;
    }
};

#endif /* __FDOC2HTML__ */

