package page.image;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Arc2D;

import org.wikiwebserver.handler.http.FormData;
import org.wikiwebserver.handler.http.interfaces.*;
import org.wikiwebserver.util.CacheableDynamicImage;

public class TemplateSprite extends CacheableDynamicImage implements HTTPResponder {
    
    private enum SpriteType { TOP, MENU, MIDDLE, BOTTOM, ROUND_BULLET, SQUARE_BULLET, BUTTON_GRADIENT }
    
    private SpriteType spriteType = SpriteType.TOP;
    
    protected void init(FormData formData) {
        
        if (formData == null) return;
        spriteType = SpriteType.valueOf(formData.getFirst("sprite").toUpperCase());
        
        switch (spriteType) {
            case TOP:
                if (!isSizeSet()) setSize(770, 100);
                break;
            case BOTTOM:
                if (!isSizeSet()) setSize(770, 65);
                break;
            case MIDDLE:
                if (!isSizeSet()) setSize(770, 10);
                break;
            case MENU:
                if (!isSizeSet()) setSize(10, 37);
                break;
            case ROUND_BULLET:
                if (!isSizeSet()) setSize(10, 10);
                break;
            case SQUARE_BULLET:
                if (!isSizeSet()) setSize(14, 14);
                break;      
            case BUTTON_GRADIENT:
                if (!isSizeSet()) setSize(10, 25);
                break;                   
        }
    }   
    
    protected void paint(Graphics2D graphics) {
        
    	Color standardBackground = new Color(204, 204, 204);
        Color standardBlue = new Color(35, 127, 190);
        Color standardGreen = new Color(138, 172, 11);
        
        graphics.setColor(Color.white);
        graphics.fillRect(0, 0, getWidth(), getHeight());

        if (spriteType == SpriteType.TOP) {
            graphics.setColor(standardBackground);
            graphics.fillRect(0, 0, getWidth(), getHeight());               
            
            int y = 5;
            int diameter = 75;
            roundedStrip(graphics, y, diameter, 10, standardBlue);
            
            paintHorizontalStrip(graphics, diameter/2+y, getHeight(), 10);
        }
        else if (spriteType == SpriteType.BOTTOM) {
            graphics.setColor(standardBackground);
            graphics.fillRect(0, 0, getWidth(), getHeight());               

            int diameter = 75;            
            int y = getHeight() - diameter;       
            roundedStrip(graphics, y, diameter, 10, standardBlue);
            
            paintHorizontalStrip(graphics, 0, getHeight()-diameter/2, 10);
            paintDividerStrip(graphics, 3, 11, standardBlue.darker());
            paintDividerStrip(graphics, 4, 11, standardBlue.brighter());
        }      
        else if (spriteType == SpriteType.MIDDLE) {
            graphics.setColor(standardBackground);
            graphics.fillRect(0, 0, getWidth(), getHeight());                

            paintHorizontalStrip(graphics, 0, getHeight(), 10);
            graphics.setColor(standardBlue);
            graphics.fillRect(10, 0, getWidth()-20, getHeight());            
            graphics.setColor(Color.white);
            graphics.fillRect(15, 0, getWidth()-30, getHeight());
        }      
        else if (spriteType == SpriteType.MENU) { 
            graphics.setColor(standardBlue);
            graphics.fillRect(0, 0, getWidth(), getHeight());    
            
            paintDividerStrip(graphics, 4, 0, standardBlue.darker());
            paintDividerStrip(graphics, 5, 0, standardBlue.brighter());
            
            paintDividerStrip(graphics, getHeight()-5, 0, standardBlue.darker());
            paintDividerStrip(graphics, getHeight()-4, 0, standardBlue.brighter());            
        }   
        else if (spriteType == SpriteType.ROUND_BULLET) { 
            int diameter = getWidth() > getHeight() ? getHeight() : getWidth();
            paintCircleBullet(graphics, 0, 0, diameter, standardGreen);         
        }     
        else if (spriteType == SpriteType.SQUARE_BULLET) {  
            int diameter = getWidth() > getHeight() ? getHeight() : getWidth();
            paintSquareBullet(graphics, 0, 0, diameter, standardGreen);         
        }         
        else if (spriteType == SpriteType.BUTTON_GRADIENT) {
            paintButtonGradient(graphics, 0, 0, getHeight(), standardGreen);
            
        }
    }

  
    private void paintHorizontalStrip(Graphics2D graphics, int y, int height, int fuzz) {
        
        graphics.fillRect(fuzz, y, getWidth()-2*fuzz, height); 
        for (int i=0; i<fuzz; i++) {
            int b = 204 - i*i;
            graphics.setColor(new Color(b, b, b));
            graphics.drawLine(i, y, i, y+height);
            graphics.drawLine(getWidth()-i-1, y, getWidth()-i-1, y+height);
        }
    }
    
    private void paintDividerStrip(Graphics2D graphics, int y, int fuzz, Color c) {
        graphics.setColor(c);
        graphics.drawLine(fuzz, y, getWidth()-fuzz-1, y);
    }    
    
    private void roundedStrip(Graphics2D graphics, int y, int diameter, int fuzz, Color c) {
        
        for (int i=0; i<10; i++) {
            int b = 204 - i*i;
            graphics.setColor(new Color(b, b, b));
            Arc2D.Float leftFuzzArc = new Arc2D.Float(i, y+i, diameter-(i*2), diameter-(i*2), 0, 360, Arc2D.PIE);
            graphics.fill(leftFuzzArc);
            Arc2D.Float rightFuzzArc = new Arc2D.Float(getWidth()-diameter+i, y+i, diameter-(i*2), diameter-(i*2), 0, 360, Arc2D.PIE);
            graphics.fill(rightFuzzArc); 
            // Top fuzz
            graphics.drawLine(diameter/2, y+i, getWidth()-(diameter/2), y+i);
            // Bottom fuzz
            graphics.drawLine(diameter/2, y+diameter-i-1, getWidth()-(diameter/2), y+diameter-i-1);            
        }
        
        graphics.setColor(c);
        Arc2D.Float leftArc = new Arc2D.Float(10, y+10, diameter-(10*2), diameter-(10*2), 0, 360, Arc2D.PIE);
        graphics.fill(leftArc);   
        Arc2D.Float rightArc = new Arc2D.Float(getWidth()-diameter+10, y+10, diameter-(10*2), diameter-(10*2), 0, 360, Arc2D.PIE);
        graphics.fill(rightArc);      
        
        graphics.fillRect(diameter/2, y+10, getWidth()-diameter, diameter-20);   
    }
    
    private void paintCircleBullet(Graphics2D graphics, int x, int y, int diameter, Color c) {
        graphics.setColor(c.darker());
        graphics.fillOval(x+diameter/6, y+diameter/6, diameter-diameter/6, diameter-diameter/6);        
        graphics.setColor(c);
        graphics.fillOval(x, y, diameter-diameter/6, diameter-diameter/6);
        graphics.setColor(c.brighter());
        graphics.fillOval(x+diameter/4, y+diameter/4, diameter/4, diameter/4);        
    }   
    
    private void paintSquareBullet(Graphics2D graphics, int x, int y, int diameter, Color c) {
        graphics.setColor(c.darker());
        graphics.fillRect(x+diameter/6, y+diameter/6, diameter-diameter/6, diameter-diameter/6);        
        
        graphics.setColor(adjustColourBrightness(c, 80));
        graphics.fillRect(x+1, y, diameter-diameter/6, diameter/2-diameter/12);  
        
        graphics.setColor(adjustColourBrightness(c, 40));
        graphics.fillRect(x+1, y+diameter/2-diameter/12, diameter-diameter/6, diameter/2-diameter/12); 
        
        graphics.setColor(c);
        graphics.drawRect(x, y, diameter-diameter/6, 2*(diameter/2-diameter/12));        
    }   
    
    private Color adjustColourBrightness(Color c, int amount) {
        int r = c.getRed()+amount;
        if (r < 0) r = 0;
        if (r > 255) r = 255;
        int g = c.getGreen()+amount;
        if (g < 0) g = 0;
        if (g > 255) g = 255;
        int b = c.getBlue()+amount;
        if (b < 0) b = 0;
        if (b > 255) b = 255;
        return new Color(r, g, b);
    }
    
    private void paintButtonGradient(Graphics2D graphics, int x, int y, int height, Color c) {
        c = adjustColourBrightness(c, 80);
        double step = (double)80 / (getHeight());
        for (int i=0; i<height; i++) {
            graphics.setColor(adjustColourBrightness(c, -(int)(i*step)));
            graphics.drawLine(0, y+i, getWidth(), y+i);  
        }
    }    
    
    public long getExpireTime() {
        return System.currentTimeMillis() + 7 * 24 * 60 * 60 * 1000;
    }    
}
