package com.marginallyclever;

import com.jogamp.opengl.*;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.awt.GLJPanel;
import com.jogamp.opengl.util.FPSAnimator;

import javax.swing.*;
import java.awt.*;
import java.util.Objects;

/**
 * Uses Modern Docking to create three kinds of DockingPanels: a tree, an output, and many text editor panels.
 * each type of panel automatically group together when created.
 */
public class Editor4 extends JFrame {
    private final FPSAnimator animator = new FPSAnimator(30);

    public static void main(String[] args) {
        var e = new Editor4();
        SwingUtilities.invokeLater(()->e.setVisible(true));
    }

    public Editor4() {
        super(Editor4.class.getSimpleName());

        // show the main window
        setSize(800, 600);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        var bar = new JMenuBar();
        var menu = new JMenu("File");
        menu.add("New");
        bar.add(menu);
        add(bar, BorderLayout.NORTH);

        // add opengl panel
        add(Objects.requireNonNull(createGLPanel()), BorderLayout.CENTER);
        var ta = new JTextArea();
        ta.setText("This is a demo text");
        add(ta, BorderLayout.SOUTH);
    }

    private Component createGLPanel() {
        GLCanvas glPanel;
        try {
            glPanel = new GLCanvas(new GLCapabilities(GLProfile.getMaxProgrammable(true)));
        } catch(GLException e) {
            e.printStackTrace();
            return null;
        }

        // add a rotating triangle
        glPanel.addGLEventListener(new GLEventListener() {
            int width,height;
            @Override
            public void init(GLAutoDrawable glAutoDrawable) {
                GL2 gl2 = glAutoDrawable.getGL().getGL2();
                // vsync on
                gl2.setSwapInterval(1);
                // enable anti-aliasing
                gl2.glEnable(GL3.GL_LINE_SMOOTH);
                gl2.glEnable(GL3.GL_POLYGON_SMOOTH);
                gl2.glHint(GL3.GL_POLYGON_SMOOTH_HINT, GL3.GL_NICEST);
                gl2.glEnable(GL3.GL_MULTISAMPLE);
                // depth testing
                gl2.glEnable(GL3.GL_DEPTH_TEST);
                gl2.glDepthFunc(GL3.GL_LESS);
                gl2.glDepthMask(true);
                // Don't draw triangles facing away from camera
                gl2.glEnable(GL3.GL_CULL_FACE);
                gl2.glCullFace(GL3.GL_BACK);
                // default blending option for transparent materials
                gl2.glEnable(GL3.GL_BLEND);
                gl2.glBlendFunc(GL3.GL_SRC_ALPHA, GL3.GL_ONE_MINUS_SRC_ALPHA);
                // clear color
                gl2.glClearColor(0.5f,0.5f,0.5f,0);
            }

            @Override
            public void dispose(GLAutoDrawable glAutoDrawable) {}

            @Override
            public void display(GLAutoDrawable glAutoDrawable) {
                GL2 gl2 = glAutoDrawable.getGL().getGL2();
                gl2.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);

                // draw a triangle
                gl2.glBegin(GL2.GL_TRIANGLES);
                gl2.glColor3f(1.0f, 0.0f, 0.0f);  gl2.glVertex2f(-0.5f, -0.5f);
                gl2.glColor3f(0.0f, 1.0f, 0.0f);  gl2.glVertex2f(0.5f, -0.5f);
                gl2.glColor3f(0.0f, 0.0f, 1.0f);  gl2.glVertex2f(0.0f, 0.5f);
                gl2.glEnd();
            }

            @Override
            public void reshape(GLAutoDrawable glAutoDrawable, int x, int y, int width, int height) {
                this.width = width;
                this.height = height;
            }
        });

        animator.add(glPanel);
        animator.start();

        return glPanel;
    }
}