package demo;

import java.awt.event.*;
import javax.media.opengl.*;
import jocode.*;

public class DemoLine extends JOApp {
    JOLine L;
    int marble = 0;
    boolean showTexture = false;
    int prevMouseX=0, prevMouseY=0;
    
    /**
     * Start the application.  run() calls setup(), handles mouse and keyboard input,
     * calls render() in a loop.
     */
    public static void main(String args[]) {
        // create the app
        DemoLine demo = new DemoLine();

        // set title, window size
        windowTitle = "Line Drawing";
        displayWidth = 800;
        displayHeight = 600;

        // start running: will call init(), setup(), draw(), mouse functions
        demo.run();
    }

    /**
     * Initialize the scene.  Called by JOApp.run().  For now the default
     * settings will be fine, so no code here.
     */
    @Override
    public void setup() {
        L = new JOLine(10f);
        L.setUVfactor(200);
        
        marble = makeTexture("images/marble.jpg");

        // turn on 2D drawing
        setOrtho();     
    }

    /**
     * Render one frame.  Called by JOApp.run().
     */
    @Override
    public void draw() {
        // Clear screen and depth buffer
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        // Select The Modelview Matrix (controls model orientation)
        gl.glMatrixMode(GL.GL_MODELVIEW);
        // Reset the coordinate system to center of screen
        gl.glLoadIdentity();
        // Place the viewpoint
        glu.gluLookAt(
            0f, 0f, 25f,   // eye position (10 units in front of the origin)
            0f, 0f, 0f,    // target to look at (the origin)
            0f, 1f, 0f);   // which way is up (Y axis)

        // activate/de-activate texture
        activateTexture(showTexture? marble : 0);
        
        // draw the line
        gl.glColor3f(1, 1, 0);

        L.draw();


        // message
        print(20,50,"Click and drag to draw, SPACE to clear, 1-9 to change width");
        print(20,20,"T to toggle texture, C to close shape, R to draw rectangle");

        // in side box: draw line in perspective
        drawRect(549,99,201,201);
        setViewport(550,100,200,200);
        setPerspective();
        glu.gluLookAt(-200,300,200, 200,300,0, 0,1,0);
        gl.glEnable(GL.GL_LIGHTING);
        setLight(GL.GL_LIGHT1, colorWhite, colorGray, colorWhite, new float[] {0f,0f,1f,0});
        setMaterial(colorWhite,.2f);
        //gl.glTranslatef(400,0,0);
        //gl.glRotatef(rotation, 0,1,0);
        //gl.glTranslatef(-400,0,0);
        //rotation += .6f;
        if (showTexture) {
            L.draw3D(100);
        }
        else {
            L.draw();
        }
        resetViewport();
        setOrtho();
        gl.glDisable(GL.GL_LIGHTING);
    }
    
    @Override
    public void keyPressed(KeyEvent _event) {
        super.keyPressed(_event);
        
        if (_event.getKeyCode() == KeyEvent.VK_SPACE) {
            L.clear();
        }
        else if (_event.getKeyCode() == KeyEvent.VK_1) {
            L.setWidth(1);
        }
        else if (_event.getKeyCode() == KeyEvent.VK_2) {
            L.setWidth(2);
        }
        else if (_event.getKeyCode() == KeyEvent.VK_3) {
            L.setWidth(5);
        }
        else if (_event.getKeyCode() == KeyEvent.VK_4) {
            L.setWidth(10);
        }
        else if (_event.getKeyCode() == KeyEvent.VK_5) {
            L.setWidth(20);
        }
        else if (_event.getKeyCode() == KeyEvent.VK_6) {
            L.setWidth(40);
        }
        else if (_event.getKeyCode() == KeyEvent.VK_7) {
            L.setWidth(70);
        }
        else if (_event.getKeyCode() == KeyEvent.VK_8) {
            L.setWidth(100);
        }
        else if (_event.getKeyCode() == KeyEvent.VK_9) {
            L.setWidth(150);
        }
        else if (_event.getKeyCode() == KeyEvent.VK_C) {
            L.close();
        }
        else if (_event.getKeyCode() == KeyEvent.VK_T) {
            showTexture = !showTexture;
        }
        else if (_event.getKeyCode() == KeyEvent.VK_R) {
            L = JOLine.makeRectangle(100,200,300,200,30);
        }
        L.rebuild();
    }
    
    /**
     * Add last mouse motion to the line, only if left mouse button is down.
     */
    @Override
    public void mouseDragged(MouseEvent _event) {
        super.mouseDragged(_event);
        
        // add mouse motion to line if left button is down, and mouse has moved more than 10 pixels 
        if (mouseButtonDown(MouseEvent.BUTTON1) && distance(prevMouseX, prevMouseY, cursorX, cursorY) > 10f) {
            // add a segment to the line
            L.point(cursorX, cursorY);
            // regenerate the line
            L.rebuild();
            // save mouse position
            prevMouseX = cursorX; 
            prevMouseY = cursorY;
        }
    }

    /**
     * start a new line
     */
    @Override
    public void mouseClicked(MouseEvent _event) {
        L.clear();
    }
    
    public float distance(int preX, int preY, int x, int y) {
        int diffX = x - preX;
        int diffY = y - preY;
        return (float)Math.sqrt((double)(diffX*diffX + diffY*diffY));
    }
}
