# Multiply.rb
# v0.1 15 APR 2008
# by Tim Inman
# Shoes.rb (http://code.whytheluckystiff.net/shoes) to be run on various platforms
# (Linux, MacOSX, Windows). Shoes.rb is a winner !!
# 
#		
#	Instructions:
#		When you click on the button and nothing happens, don't freak out.  It is loading all of my #		images from the web.  Know a better way to do this?  I can send you the images or you can
#		send me the code.
#
#	License:
#   Multiply.rb is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by the
#   Free Software Foundation; either version 2 of the License, or (at your option)
#   any later version.
#   The Twittershoes.rb is distributed in the hope that it will be useful, but
#   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
#   Please access http://www.fsf.org/ for more GNU General Public License information
#
# Credit goes to:
#		My daughter Claire who inspired the game by her need to learn multiplication tables.  
#		She has played with the game, but a promise to take her to Starbuck's was an even 
#		better motivator.  Claire is an artist and she drew the bees which are the theme of the
#		game.
#		I lifted the licensing wording from Pedro the twittershoes genius.
#		Education-world.com:  Thanks! I'm using your multiplication tables.  I hope to fix this.
#		Why the Lucky Stiff, who inspired me to code again.  I stopped programming when I was about
#		13, when a friend said, "aren't computers for geeks?"  When I found hackety hack, 
#		http://www.hacketyhack.net I wanted to learn to code again.  When I found out hackety
#		wouldn't be ready for a while I dove into rails and shoes!
#		Many of the guys on the shoes IRC, BB and _why to name a few, helped me get around problems
#		when I got stuck.
#		Greg, Giles, and Thomas from the shoes mailing list helped me with keeping score.
#		You, I am hoping you hack this, make it better and upload your version to 
#		http://the-shoebox.org

#	Caveats:
#		I don't like the look of the top buttons
#		Math gets fuzzy at the end of the quiz
# 	The scores aren't listed asthetically, because I don't really know how to display yml yet.
# 	The app starts slowly because it is downloading all the images from the web (I did this to 
#		get around the problem of the user needing to configure where the images are.) If you have 
#		a better idea, let me know.
# 	I have temporarily hot-linked someone's multiplication table, because when I made the app 
#		you couldn't have 2 shoes windows.  I have heard you can now but I haven't fixed this yet.
#		When you are taking the quiz, your brain is racing against the clock, but unnecessary
#		tabbing is slowing you down.
#		In the early days append wasn't quite working right, so the guys helped me with some work
#		arounds which probably are not necessary anymore.

class Score
  attr_accessor :secs, :name

  DB_PATH = "scores.yml"

  def initialize(opts={})
    @secs = opts[:secs] if opts[:secs]
    @name = opts[:name] if opts[:name]
  end

  def self.find_all
    result = []
    File.open( DB_PATH ) do |yf|
      YAML.load_documents( yf ) do |ydoc|
        result << ydoc
      end
    end
    result
  end

  def self.create!(opts)
    self.new(opts).save!
  end

  def save!
    f = File.open(DB_PATH, "a") do |f|
      f << YAML::dump(self).to_s
    end
  end
end

class Tables < Shoes

	url '/',					:index
	url '/scores', 		:scores
	url '/quiz', 			:quiz
	url '/buttons', :buttons
	url '/practice/(\d+)', 	:practice


	def linkbar	
		flow :width => "100%", :background => black do
			image "http://kidbuilder.net/multiply/static/practice.png", 	:click => "/buttons"
			image "http://kidbuilder.net/multiply/static/quiz.png", 			:click => "/quiz"
			image "http://kidbuilder.net/multiply/static/cheats.png", 		:click => "http://www.education-world.com/a_lesson/boxcars/images/boxcars_image13.jpg"			
			image "http://kidbuilder.net/multiply/static/scores.png", 		:click => "/scores"
		end
	end

	def result(text)
    @result.replace text									
  end

  def check
    if @edit.text.to_i == (@a * @b)
      if @b<=11
        result "correct, now the next"
        @b += 1
        @task.replace "#@a x #@b = "
        @edit.text = ""
      else
        result "correct - you're done"
				@edit.text = ""
      end
    else
      result "incorrect"
			@edit.text = ""
    end
  end  

	def quizcheck

		if @count < 12
			if @edit.text.to_i == (@a * @b)
				  result "correct, now the next"
			 			@a = 1 + rand(12)
						@b = 1 + rand(12)
						@count +=1
				    @task.replace "##@count   #@a x #@b = "
				    @edit.text = ""
		  else
		    result "incorrect"
				@edit.text = ""
		  end
		else
			@secs = (Time.now - @start).to_i
			
			result "correct - you're done.  That took you #@secs seconds."
			@edit.text = ""
			@name = edit_line :width => 100
			button "submit score" do
			Score.create! :name => (@name.text), 
										:secs => @secs
			end
		end
  end

	def index
		linkbar
		stack do
			title "Claire's Game"
		end
	end

	def buttons
		background "#D7E3F4"
		linkbar
		image "http://kidbuilder.net/multiply/static/bar.png"
		flow :top => 80, :left => 20 do			
			for num in 1..12
				image "http://kidbuilder.net/multiply/static/#{num}.png", :click => "/practice/#{num}"
			end
		end
	end

  def practice(num)
		linkbar
		title "Practice"	
		@a= num.to_i
    @b = 1
    stack do
      flow do
        @task = para "#@a x #@b = "
        @edit = edit_line
        button "check", &method(:check)
      end
      @result = para ""
    end
  end

	def quiz
		linkbar
		stack do
			title "Quiz"				
		end
		@question = flow do
			button "begin" do
				@question.clear
				@question.prepend do
				@start = Time.now
    		@a = 1 + rand(12)
   			@b = 1 + rand(12)
				@count = 1
						flow do
							@task = para "##@count    #@a x #@b = "
							@edit = edit_line
							@count += 1
							button "check", &method(:quizcheck)
      			end
     				 @result = para ""
      		end
				end
		end
 	end
 	
	def scores
		linkbar
		stack do
			title "High Scores"			
		end
		stack do
			para Score.find_all.sort_by{|s| s.secs}
		end

	end
	
end

Shoes.app :width => 400, :height => 580
