package com.brackeen.javagamebook.graphics3D;

import java.awt.*;
import java.awt.image.*;
import java.util.List;
import java.util.LinkedList;
import java.util.Iterator;

import com.brackeen.javagamebook.math3D.*;
import com.brackeen.javagamebook.graphics3D.texture.*;

/**
    ShadedSurfacePolygonRenderer jest podklasą klasy PolygonRenderer,
    która renderuje wielokąt z powierzchniami ShadedSurface. Śledzi ona
    zbudowane powierzchnie i oczyszcza wszystkie powierzchnie, które nie były
    używane w ostatniej renderowanej klatce, by oszczędzać pamięć.
*/
public class ShadedSurfacePolygonRenderer
    extends FastTexturedPolygonRenderer
{

    private List builtSurfaces = new LinkedList();

    public ShadedSurfacePolygonRenderer(Transform3D camera,
        ViewWindow viewWindow)
    {
        this(camera, viewWindow, true);
    }

    public ShadedSurfacePolygonRenderer(Transform3D camera,
        ViewWindow viewWindow, boolean eraseView)
    {
        super(camera, viewWindow, eraseView);
    }

    public void endFrame(Graphics2D g) {
        super.endFrame(g);

        // oczyść wszystkie powierzchnie, które nie były używane w tej klatce.
        Iterator i = builtSurfaces.iterator();
        while (i.hasNext()) {
            ShadedSurface surface = (ShadedSurface)i.next();
            if (surface.isDirty()) {
                surface.clearSurface();
                i.remove();
            }
            else {
                surface.setDirty(true);
            }
        }
    }

    protected void drawCurrentPolygon(Graphics2D g) {
        buildSurface();
        super.drawCurrentPolygon(g);
    }


    /**
        Buduje wszystkie powierzchnie wielokąta, jeśli jego
        powierzchnia ShadedSurface została oczyszczona.
    */
    protected void buildSurface() {
        // buduje powierzchnię, w razie potrzeby
        if (sourcePolygon instanceof TexturedPolygon3D) {
            Texture texture =
                ((TexturedPolygon3D)sourcePolygon).getTexture();
            if (texture instanceof ShadedSurface) {
                ShadedSurface surface =
                    (ShadedSurface)texture;
                if (surface.isCleared()) {
                    surface.buildSurface();
                    builtSurfaces.add(surface);
                }
                surface.setDirty(false);
            }
        }
    }

}