package model;

import java.util.ArrayList;
import java.util.List;

public class Hitbox {
	private String shape = null;// shape - Форма хитбокса. Понадобится при написании сохранения. Один из параметров в xml-file.
	private List<Point> listPointsIso = new ArrayList<Point>();
	private List<Point> listPointsCartesian = new ArrayList<Point>();
	private Point referencePoint = new Point(0, 0); //Точка отсчета хитбокса, от нее рассчитывается высота+ширина/радиус(при круге) хитбокса.
	private float widthHitbox = 0,heightHitbox = 0; // Ширина и высота хитбокса в декартовых координатах.
	private float radiusHitbox = 0;
	private Entity owner;
	
	public Hitbox(){
		initListsPoints();
	}
	public Hitbox(String shape,List<Point> listPointsIso,List<Point> listPointsCartesian){
		this.shape = new String(shape);
		this.listPointsIso = listPointsIso;
		this.listPointsCartesian = listPointsCartesian;
		initListsPoints();
	}
	public Hitbox(String informationHitbox){
		if(informationHitbox!= null) {
			initListsPoints();
		    String[] informations = informationHitbox.split(" ");
		    //в 0-м индексе всегда идет название фигуры.Так сделан наш xml.
		    shape = new String(informations[0]);
		    if(shape.equals("Rectangle")) {
		    	parseStringToRectangleHitbox(informations);
		    	createCartesianPointsFromWidthAndHeigh();
		    	convertCartesianPointsToIso();
		    }else if(shape.equals("Circle")) {
		    	parseStringToCircleHitbox(informations);
		    }
		}
	}

	private void initListsPoints() {
		if(listPointsIso.size()<1) {
			for(int i=0;i<4;i++) { 
				listPointsIso.add(new Point(0,0));
			}	
		}
		if(listPointsCartesian.size()<1) {
			for(int i=0;i<4;i++) { 
				listPointsCartesian.add(new Point(0,0));
			}	
		}
	}
	
	
	private void parseStringToRectangleHitbox(String[] informations) {
		referencePoint.x = Float.parseFloat(informations[1]);
		referencePoint.y = Float.parseFloat(informations[2]);
		widthHitbox  = Float.parseFloat(informations[3]);
		heightHitbox = Float.parseFloat(informations[4]);
		
	}
	
	private void parseStringToCircleHitbox(String[] informations) {
		referencePoint.x = Float.parseFloat(informations[1]);
		referencePoint.y = Float.parseFloat(informations[2]);
		radiusHitbox = Float.parseFloat(informations[3]);
	}
	

	public void convertIsoPointsToCartesian() {
		Point isoPoint;
		for (int i = 0 ; i<4;i++) {
			isoPoint = listPointsIso.get(i);
			cartesianToIsometric(isoPoint.x,isoPoint.y,listPointsCartesian.get(i));
		}
	}


	//+++++++
	public void convertCartesianPointsToIso() {
		Point cartesianPoint;
		for (int i = 0 ; i<4;i++) {
			cartesianPoint = listPointsCartesian.get(i);
			cartesianToIsometric(cartesianPoint.x,cartesianPoint.y,listPointsIso.get(i));
		}
	}
	//+++++++
	private void createCartesianPointsFromWidthAndHeigh(){
		Point refIsoPoint = new Point(owner.getImage().getWidth()/2+referencePoint.x,owner.getImage().getHeight()+referencePoint.y);
		Point refCartesianPoint = isometricToCartesian(refIsoPoint.x,refIsoPoint.y,new Point(0,0));
		listPointsCartesian.clear();
		listPointsCartesian.add(new Point(refCartesianPoint.x-widthHitbox,refCartesianPoint.y));
		listPointsCartesian.add(new Point(refCartesianPoint.x,refCartesianPoint.y));
		listPointsCartesian.add(new Point(refCartesianPoint.x,refCartesianPoint.y-heightHitbox));
		listPointsCartesian.add(new Point(refCartesianPoint.x-widthHitbox,refCartesianPoint.y-heightHitbox));
	}
	
	
	/**
	 * @param result - Point object to store the result
	 * @return x and y converted to isometic coords
	 * */
	public static Point cartesianToIsometric(float cartX, float cartY, Point result) {
		result.x = cartX - cartY;
		result.y = (cartX + cartY) / 2;
		return result;
	}
	
	/**
	 * @param result - Point object to store the result
	 * @return x and y converted to cartesian coords
	 * */
	public static Point isometricToCartesian(float x, float y, Point result) {
		result.x = (2 * y + x) / 2;
		result.y = (2 * y - x) / 2;
		return result;
	}	
	public void setOwnerEntity(Entity owner) {
		this.owner = owner;
	}
	public Entity getOwnerEntity() {
		return owner;
	}
	
	public String getShape() {
		return shape;
	}
	public List<Point> getListPointsIso() {
		return listPointsIso;
	}
	public List<Point> getListPointsCartesian() {
		return listPointsCartesian;
	}
	
	//not the same as toString()! the latter is for XML while printToConsole() is for console
	public void printToConsole() {
		System.out.println();
		System.out.println("|||Hitbox:");
/*		if(shape!=null&&listPoints!=null) {
			System.out.println("shape: " + shape);
			for(Point point: listPoints) {
				System.out.print("("+point.x+";"+point.y+") ");
			}
			System.out.println();
		}else {
			System.out.println("null");
		}*/
	}
	//дописать функцию возвращения listPonts и shape(форма), если будет нужно.
	// так же при написании функции возвращения нужных координат, надо их сделать целочисленными.
}
