/*
 * Renderer 5. The MIT License.
 * Copyright (c) 2022 rlkraft@pnw.edu
 * See LICENSE for details.
*/

import renderer.scene.*;
import renderer.scene.util.ModelShading;
import renderer.models_L.Disk;
import renderer.models_L.SquareGrid;
import renderer.pipeline.*;
import renderer.framebuffer.*;

import java.awt.Color;
import javax.swing.JFrame;
import java.awt.BorderLayout;

/**



*/
@SuppressWarnings("serial")
public class Circle_v4_WindowToTheWorld extends Circle_v0_Abstract
{
   /**
      This constructor instantiates the Scene object
      and initializes it with appropriate geometry.
      Then this constructor instantiates the GUI.
   */
   public Circle_v4_WindowToTheWorld()
   {
      super("Renderer 5 - Window To The World");

      // Remove the Model that's already in the Scene.
      scene.positionList.remove(0);

      // Create models for a 3x3 grid of circles and squares.
      final Model m1 = new Disk(1.0, 10, 40);
      final Model m2 = new SquareGrid(1.0, 15, 15);
      final Model m3 = new Disk(1.0, 10, 40);
      final Model m4 = new SquareGrid(1.0, 15, 15);
      final Model m5 = new Disk(1.0, 10, 40);
      final Model m6 = new SquareGrid(1.0, 15, 15);
      final Model m7 = new Disk(1.0, 10, 40);
      final Model m8 = new SquareGrid(1.0, 15, 15);
      final Model m9 = new Disk(1.0, 10, 40);

      ModelShading.setRandomColor(m1);
      ModelShading.setRandomColor(m2);
      ModelShading.setRandomColor(m3);
      ModelShading.setRandomColor(m4);
      ModelShading.setColor(m5, Color.red); // the model at the center
      ModelShading.setRandomColor(m6);
      ModelShading.setRandomColor(m7);
      ModelShading.setRandomColor(m8);
      ModelShading.setRandomColor(m9);

      // Translate the nine models.
      final Position p1 = new Position(m1, new Vector(-2,  2, 0)); // upper left-hand corner
      final Position p2 = new Position(m2, new Vector( 0,  2, 0)); // center of top edge
      final Position p3 = new Position(m3, new Vector( 2,  2, 0)); // upper right-hand corner
      final Position p4 = new Position(m4, new Vector(-2,  0, 0)); // center of left edge
      final Position p5 = new Position(m5, new Vector( 0,  0, 0)); // the model at the center
      final Position p6 = new Position(m6, new Vector( 2,  0, 0)); // center of right edge
      final Position p7 = new Position(m7, new Vector(-2, -2, 0)); // lower left-hand corner
      final Position p8 = new Position(m8, new Vector( 0, -2, 0)); // center of bottom edge
      final Position p9 = new Position(m9, new Vector( 2, -2, 0)); // lower right-hand corner

      modelToRotate = p5; // the model at the center

      // Add all the Models to the Scene.
      scene.addPosition(p1, p2, p3, p4, p5, p6, p7, p8, p9);

      print_help_message();
   }


   /**
      Get in one place the code to set up
      the view volume and the viewport.
   */
   @Override protected void setupViewing()
   {
      // Get the size of the FrameBuffer.
      final FrameBuffer fb = fbp.getFrameBuffer();
      final int wFB = fb.getWidthFB();
      final int hFB = fb.getHeightFB();

      // The viewport is the whole framebuffer.
      fb.setViewport(0, 0, wFB, hFB);

      if (mode == 1)
      {
         // 1. upper left-hand corner
         scene = scene.changeCamera(
                     Camera.projOrtho(
                            -1.0,                      // left
                            -1.0 + (2.0 * wFB) / SIZE, // right
                             1.0 - (2.0 * hFB) / SIZE, // bottom
                             1.0));                    // top
      }
      else if (mode == 2)
      {
         // 2. center of the top edge
         scene = scene.changeCamera(
                     Camera.projOrtho(
                            -wFB / (double)SIZE,       // left
                             wFB / (double)SIZE,       // right
                             1.0 - (2.0 * hFB) / SIZE, // bottom
                             1.0));                    // top
      }
      else if (mode == 3)
      {
         // 3. upper right-hand corner
         scene = scene.changeCamera(
                     Camera.projOrtho(
                             1.0 - (2.0 * wFB) / SIZE, // left
                             1.0,                      // right
                             1.0 - (2.0 * hFB) / SIZE, // bottom
                             1.0));                    // top
      }
      else if (mode == 4)
      {
         // 4. center of the right edge.
         scene = scene.changeCamera(
                     Camera.projOrtho(
                             1.0 - (2.0 * wFB) / SIZE, // left
                             1.0,                      // right
                            -hFB / (double)SIZE,       // bottom
                             hFB / (double)SIZE));     // top
      }
      else if (mode == 5)
      {
         // 5. lower right-hand corner
         scene = scene.changeCamera(
                     Camera.projOrtho(
                             1.0 - (2.0 * wFB) / SIZE,   // left
                             1.0,                        // right
                            -1.0,                        // bottom
                            -1.0 + (2.0 * hFB) / SIZE)); // top
      }
      else if (mode == 6)
      {
         // 6. centered of the bottom edge
         scene = scene.changeCamera(
                     Camera.projOrtho(
                            -wFB / (double)SIZE,         // left
                             wFB / (double)SIZE,         // right
                            -1.0,                        // bottom
                            -1.0 + (2.0 * hFB) / SIZE)); // top
      }
      else if (mode == 7)
      {
         // 7. lower left-hand corner
         scene = scene.changeCamera(
                     Camera.projOrtho(
                            -1.0,                        // left
                            -1.0 + (2.0 * wFB) / SIZE,   // right
                            -1.0,                        // bottom
                            -1.0 + (2.0 * hFB) / SIZE)); // top
      }
      else if (mode == 8)
      {
         // 8. centered of the left edge
         scene = scene.changeCamera(
                     Camera.projOrtho(
                            -1.0,                    // left
                            -1 + (2.0 * wFB) / SIZE, // right
                            -hFB / (double)SIZE,     // bottom
                             hFB / (double)SIZE));   // top
      }
      else if (mode == 9)
      {
         // 9. center of the framebuffer
         scene = scene.changeCamera(
                     Camera.projOrtho(
                            -wFB / (double)SIZE,   // left
                             wFB / (double)SIZE,   // right
                            -hFB / (double)SIZE,   // bottom
                             hFB / (double)SIZE)); // top
      }

      super.setupViewing();
   }


   /**
      Create an instance of this class which has
      the affect of creating the GUI application.
   */
   public static void main(String[] args)
   {
      // We need to call the program's constructor in the
      // Java GUI Event Dispatch Thread, otherwise we get a
      // race condition between the constructor (running in
      // the main() thread) and the very first ComponentEvent
      // (running in the EDT).
      javax.swing.SwingUtilities.invokeLater(
         () -> new Circle_v4_WindowToTheWorld()
      );
   }
}
