/* 
 
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz

This file is part of C.a.R. software.

    C.a.R. is a free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, version 3 of the License.

    C.a.R. is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 */
 
 
 package rene.zirkel.graphics;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.ImageObserver;
import java.io.IOException;
import java.io.OutputStream;

import rene.gui.Global;
import rene.zirkel.ZirkelFrame;
import rene.zirkel.objects.ConstructionObject;

public class MyGraphicsEPS extends MyGraphics {

	EPSGraphics G;
	static public int MaxR = 1000000;
	double LineWidth = 1;

	public MyGraphicsEPS(final OutputStream out, final int w, final int h) {
		G = new EPSGraphics(out, w, h, EPSGraphics.PORTRAIT, true);
	}

	public void setLineWidth(final double w) {
		LineWidth = w;
		G.setLineWidth(w);
	}

	@Override
	public void clearRect(final int x, final int y, final int w, final int h,
			final Color c) {
		G.setColor(c);
		G.fillRect(x, y, w, h);
	}

	@Override
	public void setColor(final Color c) {
		G.setColor(c);
	}

	@Override
	public void setColor(final ConstructionObject o) {
		if (o.isJobTarget()) {
			setColor(ZirkelFrame.TargetColor);
		} else if (o.selected()) {
			setColor(ZirkelFrame.SelectColor);
		} else if (o.getColorType() == ConstructionObject.THIN) {
			final int i = o.getColorIndex();
			if (o.isHidden()) {
				setColor(ZirkelFrame.BrighterLightColors[i]);
			} else {
				setColor(ZirkelFrame.LightColors[i]);
			}
		} else {
			final int i = o.getColorIndex();
			if (o.isHidden()) {
				setColor(ZirkelFrame.BrighterColors[i]);
			} else {
				setColor(ZirkelFrame.Colors[i]);
			}
		}
	}

	@Override
	public void setFillColor(final ConstructionObject o) {
		if (o.isJobTarget()) {
			setColor(ZirkelFrame.TargetColor);
		} else if (o.getColorType() != ConstructionObject.THICK) {
			final int i = o.getColorIndex();
			if (o.isHidden()) {
				setColor(ZirkelFrame.BrighterLightColors[i]);
			} else {
				setColor(ZirkelFrame.LightColors[i]);
			}
		} else {
			final int i = o.getColorIndex();
			if (o.isHidden()) {
				setColor(ZirkelFrame.BrighterColors[i]);
			} else {
				setColor(ZirkelFrame.Colors[i]);
			}
		}
	}

	@Override
	public void setLabelColor(final ConstructionObject o) {
		if (o.labelSelected()) {
			setColor(ZirkelFrame.SelectColor);
		} else if (o.isFilled()) {
			final int type = o.getColorType();
			o.setColorType(ConstructionObject.NORMAL);
			setColor(o);
			o.setColorType(type);
		} else {
			setColor(o);
		}
	}

	@Override
	public void drawRect(final double x, final double y, final double w,
			final double h) {
		G.drawRect(x, y, w, h);
	}

	@Override
	public void drawLine(final double x, final double y, final double x1,
			final double y1, final ConstructionObject o) {
		if (o.getColorType() == ConstructionObject.THICK) {
			drawThickLine(x, y, x1, y1);
		} else if (o.getColorType() == ConstructionObject.THIN) {
			drawThinLine(x, y, x1, y1);
		} else {
			drawLine(x, y, x1, y1);
		}
	}

	@Override
	public void drawLine(final double x, final double y, final double x1,
			final double y1) {
		G.drawLine(x, y, x1, y1);
	}

	@Override
	public void drawThickLine(final double c1, final double r1,
			final double c2, final double r2) {
		G.setLineWidth(3 * LineWidth);
		G.drawLine(c1, r1, c2, r2);
		G.setLineWidth(LineWidth);
	}

	public void drawThinLine(final double c1, final double r1, final double c2,
			final double r2) {
		G.setDash(4, 4);
		G.drawLine(c1, r1, c2, r2);
		G.clearDash();
	}

	@Override
	public void drawArc(final double x, final double y, final double w,
			final double h, final double a, final double b) {
		G.drawArc(x, y, w, h, a, b);
	}

	public void drawThickArc(final double x, final double y, final double w,
			final double h, final double a, final double b) {
		G.setLineWidth(3 * LineWidth);
		drawArc(x + 1, y + 1, w - 2, w - 2, a, b);
		G.setLineWidth(LineWidth);
	}

	public void drawThinArc(final double x, final double y, final double w,
			final double h, final double a, final double b) {
		G.setDash(4, 4);
		drawArc(x + 1, y + 1, w - 2, w - 2, a, b);
		G.clearDash();
	}

	@Override
	public void drawArc(final double x, final double y, final double w,
			final double h, final double a, final double b,
			final ConstructionObject o) {
		if (o.getColorType() == ConstructionObject.THICK) {
			drawThickArc(x, y, w, h, a, b);
		} else if (o.getColorType() == ConstructionObject.THIN) {
			drawThinArc(x, y, w, h, a, b);
		} else {
			drawArc(x, y, w, h, a, b);
		}
	}

	@Override
	public void drawString(final String s, final double x, final double y) {
		G.drawString(s, x, y);
	}

	@Override
	public void drawOval(final double x, final double y, final double w,
			final double h) {
		if (w < MaxR) {
			G.drawOval(x, y, w, h);
		}
	}

	public void drawThickOval(final double x, final double y, final double w,
			final double h) {
		drawOval(x, y, w, h);
		drawOval(x - 1, y - 1, w + 2, h + 2);
		drawOval(x + 1, y + 1, w - 2, h - 2);
	}

	@Override
	public void drawOval(final double x, final double y, final double w,
			final double h, final ConstructionObject o) {
		setColor(o);
		if (o.getColorType() == ConstructionObject.THICK) {
			drawThickOval(x, y, w, h);
		} else {
			drawOval(x, y, w, h);
		}
	}

	@Override
	public void fillRect(final double x, final double y, final double w,
			final double h, final boolean outline, final boolean transparent,
			final ConstructionObject o) {
		setFillColor(o);
		G.fillRect(x, y, w, h);
		if (outline) {
			setColor(o);
			G.drawRect(x, y, w, h);
		}
	}

	@Override
	public void fillArc(final double x, final double y, final double w,
			final double h, final double a, final double b,
			final boolean outline, final boolean transparent,
			final boolean arc, final ConstructionObject o) {
		setFillColor(o);
		if (arc) {
			G.fillArc(x, y, w, h, a, b);
		} else {
			G.fillChord(x, y, w, h, a, b);
		}
		if (outline) {
			setColor(o);
			G.drawArc(x, y, w, h, a, b);
		}
	}

	@Override
	public void fillOval(final double x, final double y, final double w,
			final double h, final boolean outline, final boolean transparent,
			final ConstructionObject o) {
		if (w >= MaxR) {
			return;
		}
		setFillColor(o);
		G.fillOval(x, y, w, h);
		if (outline) {
			setColor(o);
			G.drawOval(x, y, w, h);
		}
	}

	@Override
	public void fillPolygon(final double x[], final double y[], final int n,
			final boolean outline, final boolean transparent,
			final ConstructionObject o) {
		if (o.getColorType() != ConstructionObject.INVISIBLE) {
			setFillColor(o);
			G.fillPolygon(x, y, n);
		}
		if (outline) {
			setColor(o);
			G.drawPolygon(x, y, n);
		}
	}

	@Override
	public void drawImage(final Image i, final int x, final int y,
			final ImageObserver o) {
	}

	@Override
	public void drawImage(final Image i, final int x, final int y, final int w,
			final int h, final ImageObserver o) {
	}

	public void close() throws IOException {
		G.close();
	}

	int fsize;
	boolean flarge, fbold;
	int ffactor = Global.getParameter("ffactor", 130);

	@Override
	public void setDefaultFont(final int h, final boolean large,
			final boolean bold) {
		fsize = h;
		flarge = large;
		fbold = bold;
		setFont(large, bold);
	}

	@Override
	public void setFont(final boolean large, final boolean bold) {
		int size = fsize;
		if (large) {
			size = size * ffactor / 100;
		}
		if (flarge) {
			size = size * ffactor / 100;
		}
		setFont(size, bold || fbold);
	}

	@Override
	public void setFont(final int h, final boolean bold) {
		G.setFont(new Font(Global.getParameter("font.name", "dialog"),
				bold ? Font.BOLD : Font.PLAIN, h));
	}

	@Override
	public FontMetrics getFontMetrics() {
		return G.getFontMetrics();
	}

	@Override
	public void drawImage(final Image i, final double x, final double y,
			final double x1, final double y1, final double x2, final double y2,
			final ImageObserver o) {
	}

	@Override
	public Graphics getGraphics() {
		return null;
	}

	@Override
	public int stringWidth(final String s) {
		return getFontMetrics().stringWidth(s);
	}

	@Override
	public int stringHeight(final String s) {
		return getFontMetrics().getHeight();
	}

	@Override
	public int drawStringExtended(final String s, final double x, final double y) {
		drawString(s, x, y + getFontMetrics().getAscent());
		return getFontMetrics().getHeight();
	}

	@Override
	public int stringAscent(final String s) {
		return getFontMetrics().getAscent();
	}

	@Override
	public void fillOval(final double x, final double y, final double w,
			final double h, final Color WithColor) {
		try {
			G.setColor(WithColor);
			G.fillOval(x, y, w, h);
		} catch (final Exception e) {
		}
	}

	@Override
	public void fillRect(final double x, final double y, final double w,
			final double h, final Color WithColor) {
		try {
			G.setColor(WithColor);
			G.fillRect(x, y, w, h);
		} catch (final Exception e) {
		}
	}

	@Override
	public void drawDiamond(final double x, final double y, final double w,
			final boolean isThick, final ConstructionObject o) {
		final double dw = w / 2;
		final double dx[] = new double[4], dy[] = new double[4];
		dx[0] = x + dw;
		dy[0] = y;
		dx[1] = x + w;
		dy[1] = y + dw;
		dx[2] = x + dw;
		dy[2] = y + w;
		dx[3] = x;
		dy[3] = y + dw;
		if (isThick) {
			G.setColor(o.getColor());
		} else {
			G.setColor(new Color(250, 250, 250));
		}
		G.fillPolygon(dx, dy, 4);
		if (!isThick) {
			G.setColor(o.getColor());
			G.drawPolygon(dx, dy, 4);
		}
	}

	@Override
	public void drawDcross(final double x, final double y, final double w,
			final boolean isThick, final ConstructionObject o) {
		final double x1 = x + w, y1 = y + w;
		setColor(o);

		if (isThick) {
			G.setLineWidth(2 * LineWidth);
		} else {
			G.setLineWidth(LineWidth);
		}
		drawLine(x, y, x1, y1);
		drawLine(x, y1, x1, y);
		G.setLineWidth(LineWidth);
	}

	@Override
	public void setAntialiasing(final boolean bool) {
	}

	@Override
	public void drawAxisLine(final double x, final double y, final double x1,
			final double y1) {
		G.setLineWidth(LineWidth / 2);
		drawLine(x, y, x1, y1);
		G.setLineWidth(LineWidth);
	}

	@Override
	public void fillPolygon(final double[] x, final double[] y, final int n,
			final ConstructionObject o) {
		if (o.isFilled()) {
			setFillColor(o);
			G.fillPolygon(x, y, n);
		}
		if (!o.isFilled() || o.indicated() || o.selected()
				|| o.getColorType() == ConstructionObject.NORMAL) {
			setColor(o);
			G.drawPolygon(x, y, n);
		}
	}
}
