package xyz.marsavic.gfxlab.graphics3d.scene;

import xyz.marsavic.gfxlab.Color;
import xyz.marsavic.gfxlab.Vec3;
import xyz.marsavic.gfxlab.graphics3d.Light;
import xyz.marsavic.gfxlab.graphics3d.Material;
import xyz.marsavic.gfxlab.graphics3d.Scene;
import xyz.marsavic.gfxlab.graphics3d.Solid;
import xyz.marsavic.gfxlab.graphics3d.solids.Group;
import xyz.marsavic.gfxlab.graphics3d.solids.HalfSpace;
import xyz.marsavic.gfxlab.graphics3d.solids.Parallelepiped;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class Obamaborea extends Scene.Base {
    BufferedImage obomba;
    {
        try {
            obomba = ImageIO.read(new File("resources/obomba.jpg"));
        } catch (IOException e) {
            System.err.println("Couldn't load Obomba, exiting");
            System.exit(-1);
        }
    }



    public Obamaborea(int width, int floors) {
        double pillarHeight = 5;
        double pillarSpace = 5;
        Solid floor = HalfSpace.pn(Vec3.xyz(0, -1, 0), Vec3.xyz(0, 0.1, 0),
                uv -> Material.diffuseImage(obomba, uv)
        );
        Parallelepiped[][][] pillars = new Parallelepiped[floors][width][width];

        for (int i = 0; i < floors; i++) {
            for (int j = 0; j < width; j++) {
                for (int k = 0; k < width; k++) {
                    pillars[i][j][k] =
                            Parallelepiped.cxyz(
                                    Vec3.xyz((k+0.5-width/2.0)*pillarSpace,
                                            (i*1.5)*pillarHeight,
                                            (j+0.5-width/2.0)*pillarSpace),
                            1, pillarHeight, 1,
                                    uv -> Material.diffuseImage(obomba, uv));
                }
            }
        }

        List<Solid> objects = Arrays.stream(pillars).flatMap(Arrays::stream).flatMap(Arrays::stream)
                .collect(Collectors.toList());
        objects.add(floor);
        solid = Group.of(objects);

//        Light[][][] ls = new Light[floors+1][width+1][width+1];
//
//        for (int i = 0; i < floors+1; i++) {
//            for (int j = 0; j < width+1; j++) {
//                for (int k = 0; k < width+1; k++) {
//                    ls[i][j][k] = Light.pc(Vec3.xyz(((double) k - width / 2.0) * pillarSpace,
//                            (i + 0.5) * pillarHeight,
//                            ((double) j - width / 2.0) * pillarSpace), Color.gray(10));
//                }
//            }
//        }
        // Light [] lsFlat = Arrays.stream(ls).flatMap(Arrays::stream).flatMap(Arrays::stream).collect(Collectors.toList()).toArray(new Light[0]);
        Collections.addAll(lights, Light.pc(Vec3.xyz((-width/2.0) * pillarSpace,
                        0.5*pillarHeight,
                        (-width/2.0) * pillarSpace), Color.gray(30)),
                Light.pc(Vec3.xyz((width/2.0) * pillarSpace,
                        0.5*pillarHeight,
                        (-width/2.0) * pillarSpace), Color.gray(30)),
                Light.pc(Vec3.xyz((-width/2.0) * pillarSpace,
                        0.5*pillarHeight,
                        (width/2.0) * pillarSpace), Color.gray(30)),
                Light.pc(Vec3.xyz((width/2.0) * pillarSpace,
                        0.5*pillarHeight,
                        (width/2.0) * pillarSpace), Color.gray(30)),
                Light.pc(Vec3.xyz((-width/2.0) * pillarSpace,
                        (width+0.5)*pillarHeight,
                        (-width/2.0) * pillarSpace), Color.gray(30)),
                Light.pc(Vec3.xyz((width/2.0) * pillarSpace,
                        (width+0.5)*pillarHeight,
                        (-width/2.0) * pillarSpace), Color.gray(30)),
                Light.pc(Vec3.xyz((-width/2.0) * pillarSpace,
                        (width+0.5)*pillarHeight,
                        (width/2.0) * pillarSpace), Color.gray(30)),
                Light.pc(Vec3.xyz((width/2.0) * pillarSpace,
                        (width+0.5)*pillarHeight,
                        (width/2.0) * pillarSpace), Color.gray(30))
                );
    }

}
