package org.wikiwebserver.util;

import java.awt.Graphics2D;
import java.io.IOException;

import org.wikiwebserver.core.WareHouse;
import org.wikiwebserver.handler.http.FormData;
import org.wikiwebserver.handler.http.HTTPHandler;
import org.wikiwebserver.handler.http.interfaces.CacheableHTTPResponse;
import org.wikiwebserver.util.image.GraphicsHelper;
import org.wikiwebserver.util.image.GraphicsHelperFactory;

public abstract class CacheableDynamicImage implements CacheableHTTPResponse {
    
    private static final long CACHE_PERIOD = 7 * 24 * 60 * 60 * 1000;
    
    private String contentType = "image/gif";
    private FormData formData;
    private int width = 100, height = 100;
    private boolean sizeSet = false;
    private GraphicsHelper gfxHelper;
       
    protected abstract void init(FormData formData) throws IOException;
    protected abstract void paint(Graphics2D g2d) throws IOException;
    
    public void init(HTTPHandler conn) throws IOException {
        formData = conn.getRequest().getFormData();
        if (formData != null) {
            String alternateContentType = formData.getFirst("Content-Type");
            if (alternateContentType != null) {
                contentType = alternateContentType;
            }
            try {
                setSize(Integer.parseInt(formData.getFirst("w")),
                        Integer.parseInt(formData.getFirst("h")));
                sizeSet = true;
            } catch (Exception ex) {}
        }
        conn.getResponse().getHeaders().set("Content-Type", contentType);
        init(formData);
    }
    
    public String getCacheKey() {
        return cacheKeyBasedOnFormData();
    }

    public long getExpireTime() {
        return System.currentTimeMillis() + CACHE_PERIOD;
    }   
    
    public final Object respond(HTTPHandler conn) throws IOException {
        gfxHelper = GraphicsHelperFactory.create(contentType, width, height, conn.getOutputStream());
        conn.getResponse().getHeaders().set("Content-Type", gfxHelper.getContentType());
        paint(gfxHelper.createGraphics());
        gfxHelper.writeImageData();   
        return null;
    }


    public void setSize(int width, int height) {
        if (width <= 0 || height <= 0) {
            throw new IllegalArgumentException("Image too small");
        } 
        
        if (contentType.equals("image/jpeg") ||
            contentType.equals("image/gif") ||
            contentType.equals("image/png")) {
                
            if (width * height > 1000*1000) {
                throw new IllegalArgumentException("Image too large");
            }     
        }
        this.width = width;
        this.height = height;
    }
    
    public int getWidth() {
        return this.width;
    }
    
    public int getHeight() {
        return this.height;
    }
    
    public boolean isSizeSet() {
        return sizeSet;
    }
    
    public String cacheKeyBasedOnFormData() {
        if (formData == null) return "";
        return WareHouse.getMD5String(formData.toString());
    }  
}

