#!/usr/bin/env ruby -rubygems
require "sdl"
require "opengl"
require "mathn"
require "find"

# Add GL and GLUT namespaces in to make porting easier
include Gl
include Glu
include Glut

# Placeholder for the window object
window = ""

@objectsToDraw = Array.new

class PictureCollection
	attr_accessor :current_picture
	
	def initialize
		@pictures = Array.new
		@current_picture = -1
	end

	def select_next_picture
		@current_picture += 1 if (@current_picture + 1) != @pictures.size
	end

	def select_previous_picture
		@current_picture -= 1 if (@current_picture - 1) >= 0
	end

	def num_prepictures
		if @current_picture > -1
			@current_picture
		else
			0
		end
	end

	def num_postpictures
		@pictures.size - @current_picture - 1
	end

	def get_picture(pos)
		@pictures[pos] if pos > -1
	end

	def add_picture(pic)
		@pictures.push pic
		@current_picture = 0 if(@current_picture == -1)
	end

	def each
		@pictures.each do |pic|
			yield pic
		end
	end

	def length
		@pictures.length
	end
end

class Picture 
	def initialize(filename, number)
		surface = SDL::Surface.load(filename)
		texture = glGenTextures(1)
		glBindTexture(GL_TEXTURE_2D, texture[0])
		glTexImage2D(GL_TEXTURE_2D, 0, 3, surface.w, surface.h, 0, GL_RGB, GL_UNSIGNED_BYTE, surface.pixels)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
		surface = nil #hopefully this gets garbage collected
		@textureId = texture[0] # Store the Texture ID
	end

	def draw
		glBindTexture(GL_TEXTURE_2D, @textureId)
		glMatrixMode(GL_TEXTURE)
		glLoadIdentity
		glRotatef(180,0,0,1)
		glScalef(-1,1,1)
		glMatrixMode(GL_MODELVIEW)

		# Draw a rectangle
		glBegin(GL_QUADS)
		glTexCoord2f(0,0)
		glVertex3f(-1.0, -1.0, 0.0) # Bottom Left
		glTexCoord2f(1,0)
		glVertex3f( 1.0, -1.0, 0.0) # Bottom Right
		glTexCoord2f(1,1)
		glVertex3f( 1.0,  1.0, 0.0) # Top Right
		glTexCoord2f(0,1)
		glVertex3f(-1.0,  1.0, 0.0) # Top Left
		glEnd
	end
end

def init_gl_window(width = 640, height = 480)
	glViewport(0,0, width, height)
	# Background color to black
	glClearColor(0.0, 0.0, 0.0, 0)
	# Enables clearing of depth buffer
	glClearDepth(1.0)
	# Set type of depth test
	glDepthFunc(GL_LEQUAL)
	# Enable Textures
	glEnable(GL_TEXTURE_2D)
	# Enable depth testing
	glEnable(GL_DEPTH_TEST)
	# Enable smooth color shading
	glShadeModel(GL_SMOOTH)
	
	glMatrixMode(GL_PROJECTION)
	glLoadIdentity
	# Calculate aspect ratio of the window
	gluPerspective(60.0, width / height, 0.1, 100.0)
	
	glMatrixMode(GL_MODELVIEW)

end

#draw_gl_scene = Proc.new do
def draw_gl_scene
	# Clear the screen and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
	
	# Reset the view
	glMatrixMode(GL_MODELVIEW)
	glLoadIdentity

	# Draw main picture
	glTranslatef(0,0,-4)
	@objectsToDraw.get_picture(@objectsToDraw.current_picture).draw

	glLoadIdentity

	# Draw pre pictures
	if(@objectsToDraw.num_prepictures > 0)
		pos = @objectsToDraw.current_picture - 1
		glTranslatef(-3.0,0,-6.0) # Starting position
		glRotatef(45.0,0,1,0)
		while pos >= 0
			@objectsToDraw.get_picture(pos).draw
			pos -= 1
			glTranslatef(-0.3,0,-1);
		end	
	end

	glLoadIdentity

	# Draw post pictures
	if(@objectsToDraw.num_postpictures > 0)
		pos = @objectsToDraw.current_picture + 1
		glTranslatef(3.0,0,-6.0) # Starting position
		glRotatef(-45.0,0,1,0)
		while pos < @objectsToDraw.length
			@objectsToDraw.get_picture(pos).draw
			pos += 1
			glTranslatef(0.3,0,-1);
		end	
	end

	# Swap buffers for display 
	SDL.GLSwapBuffers
end


SDL.init(SDL::INIT_VIDEO)
SDL.setGLAttr(SDL::GL_DOUBLEBUFFER,1)
SDL.setVideoMode(1280, 800, 0, SDL::FULLSCREEN|SDL::OPENGL|SDL::HWSURFACE)

init_gl_window(1280, 800)

@objectsToDraw = PictureCollection.new
pos = 0
Find.find(".") do |path|
	if FileTest.directory?(path) && path != "."
		Find.prune
	elsif File.extname(path) == ".jpg"
		puts path
		@objectsToDraw.add_picture Picture.new(path, pos)
		pos += 1
	end
end

# Main Loop
loop do
	event = SDL::Event2.poll
	if !event.nil?
		break if event.is_a?(SDL::Event2::Quit)
		if event.is_a?(SDL::Event2::KeyDown) # This means it's some kind of key press
			@objectsToDraw.select_next_picture if event.sym == SDL::Key::RIGHT
			@objectsToDraw.select_previous_picture if event.sym == SDL::Key::LEFT
			exit if event.sym == SDL::Key::ESCAPE
		end
		
	end
	
	draw_gl_scene
end