import java.util.Vector;
/**
 *
 * @author user
 */
public class MapSides {

    private int[][][] sides;
    private Vector[] vsides;
    
    /*
     * Конструктор класса, инициализирует и принимает, массив координат лифтов, ширину и высоту экрана
     */
    public MapSides(int[][] lifts, int lWidth, int lHeight) {
        int[][] temp_sides = new int[][] {
            {lifts[2][1], lifts[2][0], lifts[2][0]+lWidth},
            {lifts[2][1]+lHeight, lifts[2][0], lifts[2][0]+lWidth},
            {lifts[1][0]+lWidth, lifts[1][1], lifts[1][1]+lHeight},
            {lifts[2][0]+lWidth, lifts[2][1], lifts[2][1]+lHeight}};
        vsides = new Vector[4];
        for(int i=0; i<4; i++) {
            vsides[i] = new Vector();
            for(int j=0; j<3; j++) {
                add(vsides[i], temp_sides[i][j]);
            }
        }
    }
    
    /*
     * Конструктор класса, простая инициализация
     */
    public MapSides() {
        vsides = new Vector[4];
        for(int i=0; i<4; i++) vsides[i] = new Vector();
    }

    /*
     * Добавление слоя "tiles", принмает tiles - ячейки слоя, mw и mh - ширину и высоту карты (в блоках), tw и th - ширину и высоту тайла слоя (в пикселях)
     */
    public void addLayer(int[][] tiles, int mw, int mh, int tw, int th) {
        int csb, fsb, lwsb, rwsb;
        csb = fsb = lwsb = rwsb = 0;
        boolean csLine, fsLine, lwsLine, rwsLine;
        csLine = fsLine = lwsLine = rwsLine = false;
        for(int row = 1; row < mh-1; row++) {
            for(int col = 0; col < mw; col++) {
                if(tiles[row][col] == 0) {
                    if(tiles[row-1][col] != 0) {
                        if(!csLine) {
                            csb = col;
                            csLine = true;
                        }
                    }
                    if(tiles[row-1][col] == 0) {
                        if(csLine) {
                            addSide(vsides[0], 1, col, row, csb, tw, th);
                            csLine = false;
                        }
                    }
                    if(tiles[row+1][col] != 0) {
                        if(!fsLine) {
                            fsb = col;
                            fsLine = true;
                        }
                    }
                    if(tiles[row+1][col] == 0) {
                        if(fsLine) {
                            addSide(vsides[1], 2, col, row, fsb, tw, th);
                            fsLine = false;
                        }
                    }
                }
                if(tiles[row][col] != 0) {
                    if(csLine) {
                        addSide(vsides[0], 1, col, row, csb, tw, th);
                        csLine = false;
                    }
                    if(fsLine) {
                        addSide(vsides[1], 2, col, row, fsb, tw, th);
                        fsLine = false;
                    }
                }
            }
            if(csLine) {
                addSide(vsides[0], 1, mw, row, csb, tw, th);
                csLine = false;
            }
            if(fsLine) {
                addSide(vsides[1], 2, mw, row, fsb, tw, th);
                fsLine = false;
            }
        }
        for(int col = 1; col < mw-1; col++) {
            for(int row = 0; row < mh; row++) {
                if(tiles[row][col] == 0) {
                    if(tiles[row][col-1] != 0) {
                        if(!lwsLine) {
                            lwsb = row;
                            lwsLine = true;
                        }
                    }
                    if(tiles[row][col-1] == 0) {
                        if(lwsLine) {
                            addSide(vsides[2], 3, col, row, lwsb, tw, th);
                            lwsLine = false;
                        }
                    }
                    if(tiles[row][col+1] != 0) {
                        if(!rwsLine) {
                            rwsb = row;
                            rwsLine = true;
                        }
                    }
                    if(tiles[row][col+1] == 0) {
                        if(rwsLine) {
                            addSide(vsides[3], 4, col, row, rwsb, tw, th);
                            rwsLine = false;
                        }
                    }
                }
                if(tiles[row][col] != 0) {
                    if(lwsLine) {
                        addSide(vsides[2], 3, col, row, lwsb, tw, th);
                        lwsLine = false;
                    }
                    if(rwsLine) {
                        addSide(vsides[3], 4, col, row, rwsb, tw, th);
                        rwsLine = false;
                    }
                }
            }
            if(lwsLine) {
                addSide(vsides[2], 3, col, mh, lwsb, tw, th);
                lwsLine = false;
            }
            if(rwsLine) {
                addSide(vsides[3], 4, col, mh, rwsb, tw, th);
                rwsLine = false;
            }
        }
    }
    
    /*
     * Упрощенное добавление слоя "tiles", функция аналогична методу addLayer(int[][], int, int, int, int)
     */
    public void addLayer(int[][] tiles, int tw, int th) {
        for(int row = 0; row < tiles.length; row++) {
            for(int col = 0; col < tiles[row].length; col++) {
                if(tiles[row][col] != 0) {
                    for(int i=0; i<vsides.length; i++) {
                        if(i == 0 || i == 1) addSide(vsides[i], (i == 0 ? 2 : 1), col+1, row, col, tw, th);
                        if(i == 2 || i == 3) addSide(vsides[i], (i == 2 ? 4 : 3), col, row+1, row, tw, th);
                    }
                }
            }
        }
    }
    
    /*
     * Осуществление поиска сторон карты, с учетом всех добавленных слоев
     */
    public void build() {
        sides = new int[4][][];
        for(int i=0; i<4; i++) {
            sides[i] = new int[vsides[i].size()/3][3];
            for(int j=0; j<sides[i].length; j++) {
                for(int k=0; k<3; k++) {
                    sides[i][j][k] = get(vsides[i], j*3+k);
                }
            }
        }
    }
    
    /*
     * Возвращает стороны карты
     */
    public int[][][] getSides() {
        return sides;
    }
    
    /*
     * Приватная функция, добавляет в вектор значение value
     */
    private void add(Vector vector, int value) {
        vector.addElement(""+value);
    }
    
    /*
     * Приватная функция, возвращает value из вектора под index'ом
     */
    private int get(Vector vector, int index) {
        return Integer.parseInt((String)vector.elementAt(index));
    }
    
    /*
     * Приватная функция, добавляет сторону в общий массив сторон. Принимает sides - вектор сторон, type - тип стороны (1 - потолок, 2 - пол, 3 - левая стенка, 4 - правая стенка),
     * col и row - положение стороны в массиве "tiles", b - начало (по вертикали или горизонтали) стороны, tw и th - ширина и высота ячеек(ки)
     */
    private void addSide(Vector sides, int type, int col, int row, int b, int tw, int th) {
        if(type == 1 || type == 2) {
            add(sides, (row+(type == 1 ? 0 : 1))*th);
            add(sides, b*tw);
            add(sides, col*tw);
        }
        if(type == 3 || type == 4) {
            add(sides, (col+(type == 3 ? 0 : 1))*tw);
            add(sides, b*th);
            add(sides, row*th);
        }
    }

}
