package org.artisanlogiciel.games.stl;

import java.util.Scanner;

import org.artisanlogiciel.games.Brick;
import org.artisanlogiciel.games.WallsProvider;

import java.io.OutputStream;
import java.io.IOException;

/**
 * Wall3d to create walls in 3d for stl conversion South, West North East...
 **/
public class Wall3d
{
    // 4 triangles in 2 dim space reused 3 times
    final static int BASE[][][] = { { { 0, 0 }, { 1, 0 }, { 0, 1 } }, { { 1, 0 }, { 1, 1 }, { 0, 1 } },
            { { 0, 0 }, { 1, 0 }, { 1, 1 } }, { { 0, 0 }, { 1, 1 }, { 0, 1 } } };

    final static short X = 1;
    final static short Y = 2;
    final static short Z = 4;

    // final static short AXIS[][]= {{X,Y},{-Z,Y},{X,Y},{Z,Y},{X,-Z},{X,-Z}};
    final static short AXIS[][] = { { X, Y, 0 }, { Z, Y, 0 }, { X, Y, 1 }, { Z, Y, 1 }, { X, Z, 0 }, { X, Z, 1 } };

    public final static Wall3d South = new Wall3d(10, 1, 10, 0, 0, 0);
    public final static Wall3d West = new Wall3d(1, 10, 10, 0, 0, 0);
    public final static Wall3d North = new Wall3d(10, 1, 10, 0, 10, 0);
    public final static Wall3d East = new Wall3d(1, 10, 10, 10, 0, 0);
    public final static Wall3d Ground = new Wall3d(10, 10, 2, 0, 0, 0);

    int triangle[][][] = null;

    public Wall3d(int t[][][])
    {
        triangle = t;
    }

    public Wall3d(Wall3d origin, int dx, int dy, int dz)
    {
        triangle = origin.translate(dx, dy, dz);
    }

    Wall3d(int xl, int yl, int zl, int dx, int dy, int dz)
    {
        int f = 0;
        triangle = new int[12][3][3];
        int[] factor = { xl, yl, zl };
        int[] translate = { dx, dy, dz };
        for (int i = 0; i < 12; i++)
        {
            // point in a triangle
            for (int p = 0; p < 3; p++)
            {
                short uaxis = 0;
                for (int axis = 0; axis < 2; axis++)
                {
                    short caxis = AXIS[i / 2][axis];
                    if (caxis > 0)
                    {
                        f = 1;
                    }
                    else if (caxis < 0)
                    {
                        f = -1;
                        caxis = (short) -caxis;
                    }
                    uaxis |= caxis;
                    if (caxis == X)
                    {
                        caxis = 0;
                    }
                    else if (caxis == Y)
                    {
                        caxis = 1;
                    }
                    else
                    {
                        caxis = 2;
                    }
                    // if ( f == 0 )
                    // {
                    // System.out.println("ERROR");
                    // }
                    // System.out.println("i " + i + " p " + p + " a " + caxis +
                    // " , " + BASE[i%4][p][axis] );
                    triangle[i][p][caxis] = translate[caxis] + BASE[i % 4][p][axis] * f * factor[caxis];
                }
                if ((uaxis & X) == 0)
                {
                    uaxis = 0;
                }
                else if ((uaxis & Y) == 0)
                {
                    uaxis = 1;
                }
                else
                {
                    uaxis = 2;
                }
                triangle[i][p][uaxis] = translate[uaxis] + AXIS[i / 2][2] * factor[uaxis];
            }
        }
    }

    public int[][][] translate(int dx, int dy, int dz)
    {
        int[] translate = { dx, dy, dz };
        int t[][][] = new int[12][3][3];

        for (int i = 0; i < 12; i++)
        {
            // point in a triangle
            for (int p = 0; p < 3; p++)
            {
                for (int axis = 0; axis < 3; axis++)
                {
                    t[i][p][axis] = translate[axis] + triangle[i][p][axis];
                }
            }
        }
        return t;

    }

    /**
       write triangles as stl text
     **/
    public String toString()
    {
        String s = "";
        for (int t = 0; t < 12; t++)
        {
            s += "facet normal 0 0 0\nouter loop\n";
            for (int p = 0; p < 3; p++)
            {
                s += "vertex";
                for (int a = 0; a < 3; a++)
                {
                    // s+=" t "+ t + " p " + p + " a " + a + "=" +
                    // triangle[t][p][a];
                    s += " " + triangle[t][p][a];
                }
                s += "\n";
            }
            s = s + "endloop\nendfacet\n";
        }
        return s;
    }

    public static void prepare()
    {
        System.out.println(South.toString());
        System.out.println(East.toString());
        System.out.println(North.toString());
        System.out.println(West.toString());
    }

    public static void streamWallsOut(String name, WallsProvider provider, OutputStream stream) throws IOException
    {
        int width = provider.getWidth();
        int height = provider.getHeight();
        int xl = 10;
        int yl = 10;
        int zl = 10;

        // WARNING DOWN - UP reversed ( in 2D Y is oriented to lower, in 3D it
        // is to upper ).
        stream.write(("solid " + name + "\n").getBytes());
        for (int x = 0; x < width; x++)
        {
            short walls = provider.getWalls(x, 0);
            if ((walls & Brick.UP) != 0)
            {
                stream.write(new Wall3d(South, x * xl, 0, 0).toString().getBytes());
            }
            if ((walls & Brick.LEFT) != 0)
            {
                stream.write(new Wall3d(West, x * xl, 0, 0).toString().getBytes());
            }
        }

        for (int y = 0; y < height; y++)
        {
            short walls = provider.getWalls(0, y);
            if ((walls & Brick.LEFT) != 0)
            {
                stream.write(new Wall3d(West, 0, y * yl, 0).toString().getBytes());
            }
            for (int x = 0; x < width; x++)
            {
                // south and east
                walls = provider.getWalls(x, y);
                if ((walls & Brick.DOWN) != 0)
                {
                    stream.write(new Wall3d(North, x * xl, y * yl, 0).toString().getBytes());
                }
                if ((walls & Brick.RIGHT) != 0)
                {
                    stream.write(new Wall3d(East, x * xl, y * yl, 0).toString().getBytes());
                }
		stream.write(new Wall3d(Ground, x * xl, y * yl, 0).toString().getBytes());
            }
        }

        stream.write("endsolid wall\n\n".getBytes());
    }

    public static void main(String args[])
    {

        Scanner console = new Scanner(System.in);
        int xl = console.nextInt();
        int yl = console.nextInt();
        int zl = console.nextInt();

        int dx = console.nextInt();
        int dy = console.nextInt();
        int dz = console.nextInt();

        String s = "solid wall\n";

        Wall3d instance = new Wall3d(xl, yl, zl, dx, dy, dz);

        prepare();

        s += "endsolid wall\n\n";
        System.out.println(s);
    }
}
