#
# Copyright (c) 2001 by Jim Menard <jimm@io.com>
#
# Released under the same license as Ruby. See
# http://www.ruby-lang.org/en/LICENSE.txt.
#

require 'Qt'
require 'opengl'
require 'World'
require 'Cloud'
require 'Flock'
require 'Params'
require 'Camera'

include GL

class Canvas < TQt::GLWidget

    GRASS_COLOR = [0, 0.75, 0]
    MDA_ROTATE = :MDA_ROTATE
    MDA_ZOOM = :MDA_ZOOM
    MDA_CHANGE_FOCUS = :MDA_CHANGE_FOCUS

    def initialize(parent = nil, name = '')
	super
	@grassObject = nil
#	catchEvent
    end

    def update
	updateGL()
    end

    def initializeGL()
	ClearColor(0.4, 0.4, 1.0, 0.0) # Let OpenGL clear to light blue
	@grassObject = makeGrassObject()
	ShadeModel(FLAT)
    end

    def paintGL()
	Enable(DEPTH_TEST)
	Clear(COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT)

	MatrixMode(MODELVIEW)

	camera = World.instance.camera

	LoadIdentity()
	Rotate(camera.rotation.x, 1, 0, 0)
	Rotate(camera.rotation.y, 0, 1, 0)
	Rotate(camera.rotation.z, 0, 0, 1.0)
	Translate(-camera.position.x, -camera.position.y, -camera.position.z)
	Scale(camera.zoom, camera.zoom, camera.zoom)

	CallList(@grassObject)

	World.instance.clouds.each { | cloud | cloud.draw() }
	World.instance.flock.draw()
    end

    # Set up the OpenGL view port, matrix mode, etc.
    def resizeGL(w, h)
	Viewport(0, 0, w, h)
	MatrixMode(PROJECTION)
	LoadIdentity()

#  	# left, right, bottom, top, front, back (focal_length)
	halfXSize = $PARAMS['world_width'] / 2 * 1.25
	halfYSize = $PARAMS['world_height'] / 2 * 1.25
	halfZSize = $PARAMS['world_depth'] / 2 * 1.25

#    	Frustum(-halfXSize, halfXSize, -halfYSize, halfYSize,
#  		5, halfZSize * 2)

	Ortho(-halfXSize, halfXSize, -halfYSize, halfYSize,
	      -halfZSize, halfZSize)

	MatrixMode(MODELVIEW)
    end

    def makeGrassObject
	halfXSize = $PARAMS['world_width']
	halfYSize = $PARAMS['world_depth'] / 2
	halfZSize = $PARAMS['world_height']

	list = GenLists(1)
	NewList(list, COMPILE)
	LineWidth(2.0)
	Begin(TQUADS)

	Color(GRASS_COLOR)
	# Counter-clockwise
	Vertex( halfXSize, -halfYSize,  halfZSize)
	Vertex(-halfXSize, -halfYSize,  halfZSize)
	Vertex(-halfXSize, -halfYSize, -halfZSize)
	Vertex( halfXSize, -halfYSize, -halfZSize)

	End()
	EndList()
	return list
    end

    def mousePressEvent(e)
	@mouseLoc = e.pos()
	case e.button()
	when TQt::LeftButton
	    @mouseDragAction = MDA_ZOOM
	when TQt::RightButton
	    @mouseDragAction = MDA_ROTATE
	when TQt::MidButton
	    @mouseDragAction = MDA_CHANGE_FOCUS
	end
    end

    # Rotate around sphere with right (#2) button. Zoom with left button.
    # Change focus with left button.
    def mouseMoveEvent(e)
	return if @mouseLoc.nil?

	dx = dy = 0
	if e.x() != @mouseLoc.x()
	    dx = e.x() - @mouseLoc.x() # move right increases dx
	    @mouseLoc.setX(e.x())
	end
	if e.y() != @mouseLoc.y()
	    dy = @mouseLoc.y() - e.y() # move up increases dy
	    @mouseLoc.setY(e.y())
	end

	return if dx == 0 && dy == 0

	case @mouseDragAction
	when MDA_ZOOM
	    return if (dy == 0)
	    World.instance.camera.zoom += 0.1 * -dy
	when MDA_ROTATE
	    break
	when MDA_CHANGE_FOCUS
	    break
	end
	World.instance.setupTranslation()
    end
end
