package eu.dnetlib.functionality.modular.ui.workflows.sarasvati.icons;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.googlecode.sarasvati.Node;
import com.googlecode.sarasvati.NodeToken;
import com.googlecode.sarasvati.visual.common.NodeDrawConfig;
import com.googlecode.sarasvati.visual.util.FontUtil;

import eu.dnetlib.msro.workflows.util.ProgressProvider;
import eu.dnetlib.msro.workflows.util.WorkflowsConstants;

public class ProcessJobIcon extends AbstractIcon {

	/**
	 * node token.
	 */
	private NodeToken token;

	/**
	 * Progress Bar color.
	 */
	private Color progressBarColor = Color.decode("#205fbc");

	/**
	 * Inaccurate Progress Bar color.
	 */
	private Color inaccurateProgressBarColor = Color.DARK_GRAY;

	/**
	 * Progress Bar background color.
	 */
	private Color progressBarBGColor = Color.LIGHT_GRAY;

	/**
	 * A progress provider to display
	 */
	private ProgressProvider progressProvider;

	/**
	 * constructs a blackboard node icon for a given runtime node.
	 * 
	 * @param node
	 *            node
	 * @param token
	 *            node token
	 */
	public ProcessJobIcon(final Node node, final NodeToken token, final ProgressProvider progressProvider) {
		super(node);

		this.token = token;
		this.progressProvider = progressProvider;

		setColor(NodeDrawConfig.getColor(token));

		if (token != null && token.getEnv() != null && "true".equals(token.getEnv().getAttribute(WorkflowsConstants.SYSTEM_HAS_FAILED))) {
			setFailed(true);
			setColor(Color.RED);
		}

		if (isJoin()) {
			setDashes(new float[] { DASH_FULL, DASH_EMPTY });
		}

		setTerminal(node.getGraph().getOutputArcs(node).size() == 0);

		redrawImage();
	}

	private static final Log log = LogFactory.getLog(ProcessJobIcon.class);

	@Override
	public void redrawImage(final Graphics2D gfx) {
		super.resetGfx(gfx);

		gfx.fillRoundRect(0, 0, WIDTH - 1, HEIGHT - 1, ROUND_CORNER, ROUND_CORNER);

		gfx.setColor(NodeDrawConfig.NODE_BORDER);
		final BasicStroke stroke = new BasicStroke(2, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10, getDashes(), 0);
		gfx.setStroke(stroke);
		gfx.drawRoundRect(0, 0, WIDTH - 1, HEIGHT - 1, ROUND_CORNER, ROUND_CORNER);

		gfx.setColor(Color.white);
		final int padding = 6;
		final int startX = padding;
		final int maxWidth = getIconWidth() - (padding << 1);
		FontUtil.setSizedFont(gfx, getLabel(), FONT_SIZE, maxWidth);
		final int strWidth = (int) Math.ceil(gfx.getFontMetrics().getStringBounds(getLabel(), gfx).getWidth());
		final int strHeight = gfx.getFontMetrics().getAscent();
		final int left = startX + (maxWidth - strWidth >> 1);
		final int top = getIconHeight() + strHeight >> 1;
		gfx.drawString(getLabel(), left, top);

		if (progressProvider != null && token != null && !token.isComplete()) {
			drawProgressBar(gfx);
		}

		super.resetGfx(gfx);
	}

	private void drawProgressBar(final Graphics2D gfx) {
		try {
			int total = progressProvider.getTotalValue();
			int current = progressProvider.getCurrentValue();

			if (progressProvider.isInaccurate() || current > total) {
				gfx.setColor(inaccurateProgressBarColor);
				final String text = Integer.toString(current);
				final int strWidth = (int) Math.ceil(gfx.getFontMetrics().getStringBounds(text, gfx).getWidth());
				gfx.drawString(text, getIconWidth() - strWidth - 7, getIconHeight() - 3);
			} else {
				int x = 6;
				int y = getIconHeight() - 6;

				int widthTot = getIconWidth() - x - x;

				int height = 2;
				gfx.setColor(progressBarBGColor);
				gfx.fillRect(x, y, widthTot, height);

				gfx.setColor(progressBarColor);
				int widthCurr = 0;
				if (total > 0) {
					widthCurr = Math.round(widthTot * current / total);
				}
				gfx.fillRect(x, y, widthCurr, height);
			}
		} catch (Throwable e) {
			log.warn("Error obtainig provider info", e);
			gfx.setColor(inaccurateProgressBarColor);
			final int strWidth = (int) Math.ceil(gfx.getFontMetrics().getStringBounds("?", gfx).getWidth());
			gfx.drawString("?", getIconWidth() - strWidth - 7, getIconHeight() - 3);
		}
	}

	public NodeToken getToken() {
		return token;
	}

	public void setToken(final NodeToken token) {
		this.token = token;
	}

	public Color getProgressBarColor() {
		return progressBarColor;
	}

	public void setProgressBarColor(final Color progressBarColor) {
		this.progressBarColor = progressBarColor;
	}

	public Color getProgressBarBGColor() {
		return progressBarBGColor;
	}

	public void setProgressBarBGColor(final Color progressBarBGColor) {
		this.progressBarBGColor = progressBarBGColor;
	}

	public Color getInaccurateProgressBarColor() {
		return inaccurateProgressBarColor;
	}

	public void setInaccurateProgressBarColor(final Color inaccurateProgressBarColor) {
		this.inaccurateProgressBarColor = inaccurateProgressBarColor;
	}

	public ProgressProvider getProgressProvider() {
		return progressProvider;
	}

	public void setProgressProvider(final ProgressProvider progressProvider) {
		this.progressProvider = progressProvider;
	}
}
