=begin
starfield animation, makes use of Processing::Proxy mixin
to have separate Star and Saucer classes with access to Processing
ide revised version as of 3rd July 2009
author Martin Prout
=end
require 'star'
require 'saucer'
# global constants
PHI = (1 + Math.sqrt(5))/2
STARS = 150
X_FOCUS = 800/PHI
Y_FOCUS = 150

class StarfieldSketch < Processing::App
  
  attr_reader :loc, :stars, :saucer

  def setup
    size 800, 500        
    smooth
    no_stroke
    frame_rate 60
    start_x, start_y = get_acceleration 0.005, 0.007
    if start_x.abs < 0.001 || start_y.abs < 0.0005 # guard against v. boring saucer
      start_x = 0.007 # only slightly boring saucer moves right and down initially
      start_y = 0.005
    end
    @saucer = Saucer.new X_FOCUS, Y_FOCUS, start_x, start_y, width, height
    @stars = []
    STARS.times {     # populate with stars, some bigger
      start_x, start_y = get_acceleration 0.002, 0.03
      @stars << Star.new(1.5, PVector.new(start_x, start_y)) unless stars.size % 3 == 0
      @stars << Star.new(2.2, PVector.new(start_x, start_y))  if stars.size % 3 == 0
    }  
  end

  def draw
    background 22, 22, 80
    stars.each { |star|      
      star.render
      star.update
      boundary star
    }
    fill 255, 0, 0  
    @saucer.render
    @saucer.update
    boundary @saucer
  end
  # returns a pair of random accelerations for use in PVector
  def get_acceleration min, max
          magnitude = rand * (max - min) + min
    theta = rand * TWO_PI # randomise direction using ruby rand function
    return magnitude*Math.cos(theta), magnitude*Math.sin(theta)
  end

  def boundary(star)
    star.reset_x unless star.loc.x < width - star.width/2
    star.reset_y unless star.loc.y < height - star.height/2
    star.reset_x unless star.loc.x > star.width/2
    star.reset_y unless star.loc.y > star.height/2
  end
end