package page.image;

import java.awt.*;
import java.awt.image.*;

import org.wikiwebserver.core.WareHouse;
import org.wikiwebserver.handler.http.FormData;
import org.wikiwebserver.handler.http.interfaces.*;
import org.wikiwebserver.util.CacheableDynamicImage;

public class Overview extends CacheableDynamicImage implements HTTPResponder {

    private static String mapData = null;
       
    public String getOverviewMap() {
        if (mapData == null) {
            // perform paint to get map data
            paint(new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB).createGraphics());
        }
        return mapData;
    }   
    
    protected void init(FormData formData) {
        setSize(710, 300);
    }
    
    protected void paint(Graphics2D g2d) {
        
        StringBuilder map = new StringBuilder();
        map.append("<map name='overviewImage'>");
        
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                             RenderingHints.VALUE_ANTIALIAS_ON);        
        
        g2d.setColor(Color.white);
        g2d.fillRect(0, 0, getWidth(), getHeight());

        int x, y, w, h;
        
        g2d.setColor(Color.black);
        x = 5; y=10; w=135;
        h = drawClassBox(g2d, "org.wikiwebserver.core", "WikiWebServer", new String[] {
                         "Starts WikiWebServer",
                         "Accepts connections",
                         "Maintains store & conns" }, new Color[] {
                         new Color(0, 0, 0),
                         new Color(128, 128, 0),
                         new Color(0, 0, 0)}, x, y, w);
        map.append(getLink("org/wikiwebserver/core/WikiWebServer.java", x, y, w, h));
        
        y=100; w=135;
        h = drawClassBox(g2d, "org.wikiwebserver.core", "WareHouse", new String[] {
                         "Compiles source code",
                         "Useful shared methods" }, x, y, w);   
        map.append(getLink("org/wikiwebserver/core/WareHouse.java", x, y, w, h));
        
        y=180; w=135;
        h = drawClassBox(g2d, "org.wikiwebserver.core", "SecurityMan", new String[] {
                         "Logs resource use",
                         "Restricts access" }, x, y, w);    
        map.append(getLink("org/wikiwebserver/core/SecurityMan.java", x, y, w, h));
        
        x = 155; y=130; w=130;
        h = drawClassBox(g2d, "org.wikiwebserver.core", "WikiMap", new String[] {
                         "Provides a thread-safe,",
                         "persistent store for",
                         "maintaining data" }, x, y, w);   
        map.append(getLink("org/wikiwebserver/core/WikiMap.java", x, y, w, h));        
        
       
        
        
        x = 150; y=10; w=145;
        g2d.setColor(new Color(128, 128, 0));
        h = drawClassBox(g2d, "org.wikiwebserver.core", "ConcurrentHandler", new String[] {
                         "Constructs HTTPHandler",
                         "Wraps handler execution",
                         "in Runnable."}, new Color[] {
                         new Color(128, 0, 128),
                         new Color(128, 128, 0),
                         new Color(128, 128, 0)}, x, y, w);
        map.append(getLink("org/wikiwebserver/core/ConcurrentHandler.java", x, y, w, h));        
        
        x = 305; y=10; w=140;
        g2d.setColor(new Color(128, 0, 128));
        h = drawClassBox(g2d, "org.wikiwebserver.http", "HTTPHandler", new String[] {
                         "1. Reads browser request",
                         "2. Finds requested object",
                         "3. Writes response object",
                         "Repeats (HTTP 1.1)" }, new Color[] {
                         new Color(0, 0, 128),
                         new Color(0, 128, 128),
                         new Color(128, 0, 0),
                         new Color(128, 0, 128)}, x, y, w);   
        map.append(getLink("org/wikiwebserver/handler/http/HTTPHandler.java", x, y, w, h));
        
        x = 305; y=110; w=120;
        g2d.setColor(new Color(0, 128, 128));
        h = drawClassBox(g2d, "org.wikiwebserver.http", "ObjectFinder", new String[] {
                         "Processes URL",
                         "Returns file or",
                         "HTTPResponder" }, new Color[] {
                         new Color(0, 128, 128),
                         new Color(0, 128, 128),
                         new Color(0, 128, 0)}, x, y, w);   
        map.append(getLink("org/wikiwebserver/handler/http/ObjectFinder.java", x, y, w, h));
        
        
        x = 455; y=10; w=120;
        g2d.setColor(new Color(0, 0, 128));
        h = drawClassBox(g2d, "org.wikiwebserver.http", "HTTPInputStream", new String[] {
                         "Reads request",
                         "Parses headers",
                         "Parses posted data" }, x, y, w); 
        map.append(getLink("org/wikiwebserver/handler/http/HTTPInputStream.java", x, y, w, h));
        
        x = 585; y=10; w=120;
        h = drawClassBox(g2d, "org.wikiwebserver.http", "HTTPRequest", new String[] {
                         "Holds request info",
                         "Holds HTTP headers",
                         "Holds posted data" }, x, y, w);  
        map.append(getLink("org/wikiwebserver/handler/http/HTTPRequest.java", x, y, w, h));
        
        x = 585; y=100; w=120;
        g2d.setColor(new Color(128, 0, 0));
        h = drawClassBox(g2d, "org.wikiwebserver.http", "HTTPResponse", new String[] {
                         "Holds response info",
                         "Holds HTTP headers" }, x, y, w); 
        map.append(getLink("org/wikiwebserver/handler/http/HTTPResponse.java", x, y, w, h));
        
        x = 455; y=100; w=120;
        h = drawClassBox(g2d, "org.wikiwebserver.http", "HTTPOutputStream", new String[] {
                         "Constructs response",
                         "Writes headers",
                         "Writes response" }, new Color[] {
                         new Color(128, 0, 0),
                         new Color(128, 0, 0),
                         new Color(0, 128, 0)}, x, y, w);   
        map.append(getLink("org/wikiwebserver/handler/http/HTTPOutputStream.java", x, y, w, h));
        
        
        x = 335; y=210; w=170;
        g2d.setColor(new Color(0, 128, 0));
        drawClassBox(g2d, "org.wikiwebserver.http.interfaces", "HTTPResponder", new String[] {
                     "Implement this interface to",
                     "return custom web objects"  }, x, y, w); 
        map.append(getLink("org/wikiwebserver/handler/http/interfaces/HTTPResponder.java", x, y, w, h));
        
        x = 515; y=210; w=155;
        g2d.setColor(new Color(192, 0, 0));
        h = drawClassBox(g2d, "org.wikiwebserver.http", "HTTPException", new String[] {
                         "Wraps exceptions for web-",
                         "based error reporting"  }, x, y, w);   
        map.append(getLink("org/wikiwebserver/handler/http/HTTPException.java", x, y, w, h));        
        
        
        mapData = map.toString();     
    }
    
    private int drawClassBox(Graphics2D g2d, String pkg, String cn, String[] info, int x, int y, int w) {
        return drawClassBox(g2d, pkg, cn, info, null, x, y, w);
    }
    
    private int drawClassBox(Graphics2D g2d, String pkg, String className, String[] info,
                             Color[] colours, int x, int startY, int width) {
        
        int y = startY;
        Color c = g2d.getColor();
        Font sF = new Font(g2d.getFont().getFontName(), Font.PLAIN, 10);
        g2d.setFont(sF);
        y += g2d.getFontMetrics().getAscent();
        g2d.drawString(pkg, x+3, y);
        
        Font lF = new Font(g2d.getFont().getFontName(), Font.BOLD, 12);
        g2d.setFont(lF);
        y += g2d.getFontMetrics().getAscent();  
        g2d.drawString(className, x+3, y);
        y += g2d.getFontMetrics().getDescent();
        
        Font mF = new Font(sF.getFontName(), Font.PLAIN, 11);
        g2d.setFont(mF);
        int mFH = g2d.getFontMetrics().getAscent();  
        y += mFH;
        for (int i=0; i<info.length; i++) {
            if (colours != null) {
                g2d.setColor(colours[i]);
            }
            g2d.drawString(info[i], x+3, y);
            y += mFH;
        }
        y -= g2d.getFontMetrics().getDescent();
        
        g2d.setColor(c);
        g2d.drawRect(x, startY, width, y-startY);     
        
        return y-startY;
    }
    
    private String getLink(String path, int x, int y, int w, int h) {
        return "<area shape='rect' coords='"+x+","+y+","+(x+w)+","+(y+h)+"' " +
               "href='" + WareHouse.SOURCE_EDITOR_URL + "?path=" + path + "'>";

    } 
}
