package mishin870;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.Sprite;

public class Isometry3DTiledLayer{
Image[] t;
int[][] cells;
public int wid;
public int hei;
public int zhei;
int widi;
int heii;
public int x=0;
public int y=0;
public boolean visible=true;
int maxIndex;
public boolean type=true;

public Isometry3DTiledLayer(int columns,int rows,int zHeight,Image image,int tileWidth,int tileHeight){
this.wid = columns;
this.hei = rows;
this.zhei = zHeight;
this.widi = tileWidth;
this.heii = tileHeight;
cells = new int[zhei][wid*hei*zhei];
fillAll(0);
updateImages(image,tileWidth,tileHeight);
}

//Функция, которая превращает исходную картинку img в массив картинок.
void updateImages(Image img,int widi,int heii){
int numX = img.getWidth()/widi;
int numY = img.getHeight()/heii;
int numImgs = numX*numY;
maxIndex = numImgs;
t = new Image[numImgs];
for(int ix=0;ix<numX;ix++){
	for(int iy=0;iy<numY;iy++){
		t[ix+iy*numX] = getPartImg(img,ix*widi,iy*heii,widi,heii);
	}
}
}

public void paint(Graphics g){
/*Стандартная публичная функция отрисовки, она рисует с помощью метода drawLine
несколько линий тайлов по ширине IsometryTiledLayer
*/
if(visible){
	for(int iz=0;iz<zhei;iz++){
		for(int i=0;i<wid;i++){
			drawLine(g,i,iz);
		}
	}
}
}

//Функция, которая рисует 1 "вертикальную" (в изометрическом виде) линию тайлов
void drawLine(Graphics g,int i,int iz){
int dx=0;
int dy=0;
if(type){
	dy=y+i*heii/4;
	dx=i*(widi/2)+x;
} else {
	dy=y;
	dx=i*widi+x;
}
dy-=iz*heii/2;
for(int temp=0;temp<hei;temp++){
	int cellNum = i+temp*wid;
	g.drawImage(t[cells[iz][cellNum]],dx,dy,20);
	dx-=widi/2;
	dy+=heii/4;
}
}

//Вспомогательная функция для получения куска Image.
static Image getPartImg(Image img,int x, int y, int width, int height)
{
Image ret = Image.createImage(img,x,y,width,height,Sprite.TRANS_NONE);
return ret;
}

//Публичные методы для управления IsometryTiledLayer

//Стандартный setPosition
public void setPosition(int x,int y){
this.x = x;
this.y = y;
}

public void move(int x,int y){
/*Метод, который прибавляет к x и y класса x и y в аргументах функции
Например: было x=2,y=4. после move(0,-2) будет x=2,y=2
*/
this.x+=x;
this.y+=y;
}

//Относительная заливка тайла, например если было cells[0]=1, вызвать ratherSetCell(0,0,1), то будет cells[0]=2
public void ratherSetCell(int col,int row,int z,int ratherIndex){
int temp=cells[z][col+row*wid];
temp+=ratherIndex;
if(temp>=maxIndex){temp=0;}
if(temp<0){temp=maxIndex-1;}
cells[z][col+row*wid] = temp;
}

//То же самое, но по иднексу внутри массива cells
public void ratherSetCell(int i,int z,int ratherIndex){
int temp=cells[z][i];
temp+=ratherIndex;
if(temp>=maxIndex){temp=0;}
if(temp<0){temp=maxIndex-1;}
cells[z][i] = temp;
}

//setVisible, опять без комментариев
public void setVisible(boolean visible){
this.visible = visible;
}

//Метод, который заливает ВСЕ тайлы выбранным
public void fillAll(int tileIndex){
for(int iz=0;iz<zhei;iz++){
	for(int i=0;i<wid*hei;i++){
		setCell(i,iz,tileIndex);
	}
}
}

//Метод, который заливает участок поля выбранным тайлом
public void fillCells(int col, int row,int z, int numCols, int numRows,int numZ, int tileIndex){
for(int fz=z;fz<z+numZ;fz++){
	for(int fx=col;fx<col+numCols;fx++){
		for(int fy=row;fy<row+numRows;fy++){
			setCell(fx,fy,fz,tileIndex);
		}
	}
}
}

//Заливка 1 тайла по индексу внутри массива cells
public void setCell(int i,int z,int tileIndex){
if(tileIndex>=maxIndex){tileIndex=0;}
if(tileIndex<0){tileIndex=maxIndex-1;}
cells[z][i] = tileIndex;
}

public void setType(boolean type){
this.type = type;
}

//Заливка 1 тайла по x и y
public void setCell(int col,int row,int z,int tileIndex){
if(tileIndex>=maxIndex){tileIndex=0;}
if(tileIndex<0){tileIndex=maxIndex-1;}
cells[z][col+row*wid] = tileIndex;
}

}