package cz.vutbr.feec.imageprocessing.op.segmentation.watershed;

import java.awt.Color;
import java.util.ArrayList;


public class WPoint {
	
	public static final class LblType {
		public final static int INIT    = -1;
		public final static int MASK    = -2;
		public final static int FICTIVE = -3;
		public final static int WSHED   = -4;
	}
	

	//-------------fields
	private ImageStructure parentImage;
	private int posX;
	private int posY;
	private Boolean wasWaterShad = false;
	private Color color;
	private int label;
	private int distance;
	
	//-------------constructors
	
	public WPoint (ImageStructure parentImage, int posX, int posY, Color color) {
		this.parentImage = parentImage;
		this.posX = posX;
		this.posY = posY;
		this.color = color;
		this.label = LblType.INIT;
		this.distance = 0;
	}
	
	public WPoint () {
		label = LblType.FICTIVE;
	}
	
	//-------------methods
	public int getPosX() {
		return posX;
	}
	
	public int getPosY() {
		return posY;
	}
	
	public int getRed() {
		return color.getRed();
	}
	
	public int getGreen() {
		return color.getGreen();
	}
	
	public int getBlue() {
		return color.getBlue();
	}
	
	public int getGray() {
		return calculateGray();
	}
	
	private int calculateGray() {
		if (RgbToGSModel.RGB_TO_GS.equals(getConvertModel())) 
			return (int) (0.2126 * getRed() + 0.7152 * getGreen() + 0.0722 * getBlue());
		return  (int) (getRed() + getGreen() + getBlue())/3;
	}
	
	private RgbToGSModel getConvertModel() {
		if (parentImage != null)
			return parentImage.getConvertModel();
		return RgbToGSModel.RGB_TO_GS;
	}

	
	public int getLabel() {
		return label;
	}
	
	
	public int getDistance() {
		return distance;
	}
	
	
	public boolean isWShed() {
		return label == LblType.WSHED;
	}
	
	public boolean isNotWShed() {
		return !isWShed();
	}
	
	public boolean isMask() {
		return label == LblType.MASK;
	}
	
	public boolean isLabelOverZero() {
		return label > 0;
	}
	
	
	public boolean hasLabeledNeighbor() {
		for (WPoint neigbour : this.getNeighbors()) {
			if (neigbour.isLabelOverZero())
				return true;
		}
		return false;
	}


	public void setLabelToMask() {
		setLabel(LblType.MASK);
	}
	
	public void setLabelToWshed() {
		setLabel(LblType.WSHED);
	}
	
	public void setLabel(int label) {
		if (label == LblType.WSHED) 
			this.wasWaterShad = true;
		this.label = label;
	}

	public void setDistance(int distance) {
		this.distance = distance;
	}

	public void setColor(int red, int green, int blue) {
		this.color = new Color(red, green, blue);
	}

	public ArrayList<WPoint> getNeighbors() {
		return this.parentImage.getNeighborsFor(this.posX, this.posY);
	}

	public Color getColor() {
		if (color != null)
			return color;
		return Color.black;
	}
	
	public Boolean wasWaterShad() {
		return wasWaterShad;
	}

	
	public ArrayList<Region> findRegionsAround(Region[] regions) {
		ArrayList<Region> regionsAround = new ArrayList<Region>();
		for (WPoint neighbor : this.getNeighbors()) {
			if (neighbor.isLabelOverZero() && regions[neighbor.getLabel()].getNumOfPointsInRegion() >0 && !regionsAround.contains(regions[neighbor.getLabel()])) 
				regionsAround.add(regions[neighbor.getLabel()]);
		}
		return regionsAround;
	}
	
}
