#include <string.h>
#include <glib.h>

#include "ContentTransposer.h"

class TextFileTransposer : public ContentTransposer 
{
public:
    TextFileTransposer(HttpRequestListener* l);
    ~TextFileTransposer();
    bool data(const HttpRequest*, const char* data, int len);
    bool finished(const HttpRequest*);
    bool header(const HttpRequest* r, const HttpHeader *header); 

    static bool contentTypeMatches(const gchar* contentType);
private:
    bool html_sent;    
};

class ImageTransposer : public ContentTransposer 
{
public:
    ImageTransposer(HttpRequestListener* l);
    ~ImageTransposer();
    bool data(const HttpRequest*, const char* data, int len);
    bool finished(const HttpRequest*);
    bool header(const HttpRequest* r, const HttpHeader *header); 

    static bool contentTypeMatches(const gchar* contentType);
private:
    bool html_sent;
};



ContentTransposer::ContentTransposer(HttpRequestListener* aforwardee)
    :forwardee(aforwardee)
    ,switched(false)
{
}

ContentTransposer::~ContentTransposer()
{
    delete forwardee;
}

bool ContentTransposer::started(const HttpRequest* r) 
{
    return forwardee->started(r);
}

bool ContentTransposer::finished(const HttpRequest* r) 
{
    return forwardee->finished(r);
}

bool ContentTransposer::headersEnd(const HttpRequest* r, int status)
{
    return forwardee->headersEnd(r, status);
}

bool ContentTransposer::data(const HttpRequest* r, const char* data, int len) 
{
    return forwardee->data(r, data,len);
}

bool ContentTransposer::error(const HttpRequest* r) 
{
    return forwardee->error(r);
}

bool ContentTransposer::header(const HttpRequest* r, const HttpHeader *header) 
{
    switch (header->type()){
    case HttpHeader::ContentType:
    {
	const HttpHeaderContentType* ct
	    = static_cast<const HttpHeaderContentType*>(header);	    

	const gchar* contentType = ct->contentType();
	if (!switched) {
	    if (TextFileTransposer::contentTypeMatches(contentType)) {
		forwardee = new TextFileTransposer(forwardee);
	    } else if (ImageTransposer::contentTypeMatches(contentType)) {
		forwardee = new ImageTransposer(forwardee);
	    }
	    // avoid multpile level of forwarding
	    switched = true;
	}
	
	break;
    }       
    default:
	break;
    }

    return forwardee->header(r, header);
}

bool ContentTransposer::resolving(const HttpRequest*r)
{
    return forwardee->resolving(r);
}
  
bool ContentTransposer::authenticate(HttpRequest* r)
{
    return forwardee->authenticate(r);
}




TextFileTransposer::TextFileTransposer(HttpRequestListener* l)
    : ContentTransposer(l)
      ,html_sent(false)
{    
}


TextFileTransposer::~TextFileTransposer()
{
}

bool TextFileTransposer::data(const HttpRequest* r, const char* data, int len) 
{
    if (!html_sent) {
	static const gchar *pre_content = "<html><head><title>%s/title><body><pre>\n";

	const gchar* content = g_strdup_printf(pre_content, r->url());
	int content_len = strlen(content);

	html_sent=true;

	forwardee->data(r, content, content_len);
    }

    return forwardee->data(r, data, len);
}

bool TextFileTransposer::finished(const HttpRequest* r)
{
    static const gchar *content = "</pre></body></html>\n";
    static int content_len = strlen(content);

    forwardee->data(r, content, content_len);
    return forwardee->finished(r);
}

bool TextFileTransposer::contentTypeMatches(const gchar* contentType)
{
    if (strcmp(contentType, "text/plain")==0) return true;
    return false;
}


bool TextFileTransposer::header(const HttpRequest* r, const HttpHeader *header) 
{
    switch (header->type()){
    case HttpHeader::ContentType:
    {	
	HttpHeaderContentType fakeHeader("text/html");
	return forwardee->header(r, &fakeHeader);
    }
    default:
	break;
    }

    // dont forward any other headers (we might get for example content length..)
    return false;
}


ImageTransposer::ImageTransposer(HttpRequestListener* l)
    : ContentTransposer(l)
      ,html_sent(false)
{
}


ImageTransposer::~ImageTransposer()
{
}


bool ImageTransposer::data(const HttpRequest* r, const char* data, int len) 
{
    if (!html_sent) {
	static const gchar *pre_content = "<html><head><title>Image: %s</title><body><img src=\"%s\"></img></body></html> \n";

	const gchar* content = g_strdup_printf(pre_content, r->url(), r->url());
	 int content_len = strlen(content);


	html_sent=true;

	forwardee->data(r, content, content_len);
    }

    // discard the data
    return true;
}

bool ImageTransposer::finished(const HttpRequest* r)
{
    forwardee->finished(r);

    return true;
}


bool ImageTransposer::header(const HttpRequest* r, const HttpHeader *header) 
{
    switch (header->type()){
    case HttpHeader::ContentType:
    {	
	HttpHeaderContentType fakeHeader("text/html");
	return forwardee->header(r, &fakeHeader);
    }
    default:
	break;
    }

    // dont forward any other headers (we might get for example content length..)
    return false;
}

bool ImageTransposer::contentTypeMatches(const gchar* contentType)
{
    if (g_str_has_prefix(contentType, "image/") == TRUE) return true;
    return false;
}

