package gamegui;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.image.ImageObserver;
import java.awt.Image;
import java.awt.Color;
import java.awt.GraphicsEnvironment;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.FontMetrics;
import java.awt.Font;
import java.util.ArrayList;

public class ScrollList extends Member
{
    private ArrayList<Listable> lstObjects;
    private Listable selectedItem;
    private Font font;
    private int fontHeight;
    private int textStart;
    private boolean change;
    
    public ScrollList(final String newName, final int newX, final int newY, final int newWidth, final int newHeight, final Font font, final FontMetrics metrics) {
        super(newName, newX, newY, newWidth, newHeight);
        this.lstObjects = new ArrayList<Listable>();
        this.selectedItem = null;
        this.font = font;
        if (metrics == null) {
            this.fontHeight = 0;
        }
        else {
            this.fontHeight = metrics.getHeight();
        }
        this.textStart = 0;
        this.change = false;
    }
    
    public ArrayList<Listable> getList() {
        return this.lstObjects;
    }
    
    public Listable getSelected() {
        return this.selectedItem;
    }
    
    public boolean isChanged() {
        return this.change;
    }
    
    public void changeHandled() {
        this.change = false;
    }
    
    public void deselect() {
        this.selectedItem = null;
    }
    
    @Override
    public void clear() {
        this.lstObjects.clear();
        this.selectedItem = null;
        this.textStart = 0;
        this.changeHandled();
    }
    
    @Override
    public boolean handleEvent(final MouseEvent e) {
        if (!this.getScrollBar().handleEvent(e)) {
            return false;
        }
        if (e.getY() < this.getY() + this.getScrollBar().getWidth()) {
            this.changeTextStart(-30);
        }
        else if (this.getY() + this.getHeight() - this.getScrollBar().getWidth() < e.getY()) {
            this.changeTextStart(30);
        }
        return true;
    }
    
    private void changeTextStart(final int increment) {
        this.textStart += increment;
        int listHeight = 0;
        if (this.lstObjects.size() > 0) {
            final Listable e = this.lstObjects.get(0);
            listHeight = e.getHeight() * (int)Math.ceil(this.lstObjects.size() / (this.getWidth() / e.getWidth())) + e.getYOffset();
        }
        if (listHeight > this.getHeight() && this.textStart >= listHeight - this.getHeight()) {
            this.textStart = listHeight - this.getHeight();
            this.getScrollBar().setPosition(this.getScrollBar().getMaxSize() - this.getScrollBar().getSize());
        }
        else if (this.textStart < 0 || listHeight <= this.getHeight()) {
            this.textStart = 0;
            this.getScrollBar().setPosition(0);
        }
        else {
            this.getScrollBar().setPosition(this.textStart * this.getScrollBar().getMaxSize() / listHeight);
        }
    }
    
    public int getTextStart() {
        return this.textStart;
    }
    
    @Override
    public void draw(final Graphics g) {
        final GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
        final GraphicsDevice device = env.getDefaultScreenDevice();
        final GraphicsConfiguration gc = device.getDefaultConfiguration();
        final BufferedImage source = gc.createCompatibleImage(this.getWidth(), this.getHeight());
        final Graphics2D srcGraphics = source.createGraphics();
        srcGraphics.setColor(Color.green);
        if (this.font != null) {
            srcGraphics.setFont(this.font);
        }
        int listHeight = 0;
        Listable e = null;
        if (this.lstObjects.size() > 0) {
            e = this.lstObjects.get(0);
            listHeight = e.getHeight() * (int)Math.ceil(this.lstObjects.size() / (this.getWidth() / e.getWidth())) + e.getYOffset();
        }
        int numPerRow = 0;
        if (e != null) {
            numPerRow = this.getWidth() / e.getWidth();
        }
        for (int x = 0; x < this.lstObjects.size(); ++x) {
            this.lstObjects.get(x).draw(e.getHeight() * (x % numPerRow) + e.getXOffset(), this.fontHeight + x / numPerRow * e.getHeight() - this.textStart, srcGraphics);
        }
        g.drawImage(source, this.getX(), this.getY(), null);
        g.setColor(Color.red);
        g.drawRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
        if (listHeight > this.getHeight()) {
            this.getScrollBar().setSize(this.getScrollBar().getMaxSize() * this.getHeight() / listHeight);
        }
        else {
            this.getScrollBar().setSize(this.getScrollBar().getMaxSize());
        }
        this.getScrollBar().draw(g);
    }
}
