-- Simple Random Sentence Generator v.1
-- Programming, graphics, and design: Psyberjock
-- Idea: Psyberjock and Noble
-- Sources: lua.org, engrish.com (for vocabulary ideas), luaplayer.org, and EvilMana's tuts.
--          Thanks guys!! Couldn't have done it so quickly without you! 
--
-- The original idea for this program is a simple random Engrish generator.
-- While making the program I realized that it could be expanded to do far more.
-- 
-- I plan on making these expansions in the future, but feel free to use any of this code as you wish.
-- It's as free as can be.
--
-- If you'd like to mod this to do different languages or other crazy sentences, let me give some hints
-- on producing consistently interesting sentences. Patterns are very important and describing your word
-- categories is perhaps the only more important things. Luckily for me, I have a degree in linguistics.
-- Knowing how language is used and which words fall into which categories is very important.
-- Still, the nature of randomness prevents perfectly interesting sentences every time, so don't worry too
-- much if you crank out some useless sentences as well.
--
-- Oh, I know my code is a mess. I tried to organize it while writing it, but somethings just
-- piled up. I hope I have at least documented it well enough.

-- Sorry for the mess. Here's the start of my Globals.
oldpad = Controls.read()
-- This prototype is used to temporarily hold my generated sentence so it can be outputted to screen or file without making a whole new sentence on accident.
thispattern = nil
backuppattern = nil
toggle = nil
oldfav = nil
favsread = io.open("favs.txt", "r")
green = Color.new(0, 255, 0)
blue = Color.new(0, 0, 255)
red = Color.new(255, 0, 0)
grey = Color.new(200, 200, 200)
title = Image.load("srsgtitle.png")
mainback = Image.load("srsgmain.png")

-- Function for my main screen display.
function main()
screen:blit(0,0,mainback)
screen:print(140, 170, "", green)
screen:print(140, 180, "<up> Generate a sentence.", green)
screen:print(140, 190, "<right> Save to favorites.", green)
screen:print(140, 200, "<down> Back one sentence.", grey)
screen:print(140, 210, "<left> Review favorites.", blue)
screen:print(140, 220, "", green)
screen:print(140, 230, "<menu> Exit SRSG.", red)
screen:print(140, 240, "", red)
end

-- Prototype for my pattern table which seems to need to be in my main loop.
patternArray={}
-- Currently all of my data is hardcoded. Here's the word lists seperated by word type.
artArray={"an", "a", "the", "this", "these", "those", "that"}
nitemArray={"book", "box", "note", "sharp pen", "vase", "towel", "elevator", "bag", "utensil", "tool", "case", "rack"}
naliveArray={"boy", "girl", "man", "woman", "cat", "dog", "pig", "cow", "cock", "mother", "father", "friend"}
nemotionArray={"feel", "pleasure", "nostalgia", "secret", "feeling", "looks", "happiness", "sadness", "joy", "fear", "love", "hate"}
nthingArray={"air", "highway" }
nabstrArray={"looks", "ride"}
vitemArray={"read", "bring", "hold", "take", "contain", "make", "write"}
vitemprogArray={"reading", "bringing", "holding", "taking", "containing", "making", "writing"}
vitempastArray={"read", "brought", "held", "took", "contained", "made", "wrote"}
vArray={"come", "meet", "spend", "run", "play", "bowl", "relax", "rest", "take", "contain", "stand", "drink", "eat", "make"}
vprogArray={"coming", "meeting", "spending", "running", "playing", "bowling", "relaxing", "containing", "resting", "taking", "standing", "making"}
vpastArray={"ran", "came", "met", "spent", "played", "bowled", "relaxed", "rested", "took", "contained", "stood", "made"}
auxArray={"can", "can not", "do", "do not", "be able"}
adjArray={"soft", "nice", "free", "secret", "rainy", "nostalgic", "delicious", "pretty", "calm", "relaxed", "peaceful", "nervous", "excited", "gay", "clam", "calm", "anxious", "ageless", "ancient", "happy", "sad", "good", "angry", "bad", "fine", "dandy", "sleepy"}
advArray={"hardly", "well", "poorly", "gently", "together", "strongly", "plentifully", "greatly", "kindly", "quickly", "very"}
prepArray={"on", "of", "for", "in", "by", "from", "to", "with"}
conjArray={"and", "but", "or", "because"}
pronArray={"he", "she", "it", "I", "you", "they", "we"}
nameArray={"Don Don", "Cubic Cube", "Mary", "Tim Tom", "Miffy", "Spoony", "Tammy", "Stanley", "Mink", "Pim Pim", "Sodami", "Fragley" }
productArray={"GOOD BAG", "QUALITY NOTE", "GLASS BOWL", "NICE CHILD", "CD RACK", "HANDY BOX", "SWEET TOWEL", "SPIRAL NOTE"}
clauseArray={"when", "that", "which", "where", "who"}
interArray={"Oh my got!", "Oh my god!", "Oh no!", "Yay!", "Wonderful!", "Great!", "Bravo!", "That's great!", "Holy smork!", "What a?!", "What!?"}
copulaArray={"is", "am", "are", "is being", "was", "was being"}
pleaseArray={"please", "prease"}
possArray={"my", "your", "his", "her", "its", "mine", "hers"}
timeArray={"hour", "minute", "second", "day", "week", "month", "year", "decade", "century", "lifetime", "afternoon", "evening", "morning", "lunchtime", "hours", "minutes", "seconds", "days", "weeks", "months", "years", "decades", "centuries", "lifetimes", "afternoons", "evenings", "mornings", "lunchtimes"}
suggArray={"let's", "shall we"}
compArray={"good", "better", "best", "bad", "worse", "worst"}

screen:clear()
screen:blit(0,0,title)
screen:print(118, 235, "Press <start> to Continue...", green)
screen.flip()


while true do
screen.waitVblankStart()
pressstart = Controls.read()
if pressstart:start() then
break
end
end

screen:clear()
main()
screen:print(100,65, "Please choose an option to begin...", green)
screen.flip()

-- This is my function for generating random numbers. The random generator is seeded by the os.time
-- and is then fed into the random generator, one item at a time, AND returns an interger based on
-- (found withing the range of) the number of items in the respective table.
function rand(numer) 
randnumer = math.random(numer)
return randnumer
end

while true do
-- seeding my random generator within my main loop to allow constantly updated seeds
math.randomseed(os.time())
pad = Controls.read()

-- Here's my sentence patterns. They reference a category's table and randomly select an entry.
-- Each random number is restricted to the available table entries by using table.getn to set the
-- upper range of the randomly generated numbers. Later on in the code the patterns themselves are randomly
-- selected. Each pattern will create a basic sentence and the details are the only things that
-- actually change. Depending on how many patterns you have and how well you categorize your
-- word lists, your sentence quality and variety can rise or fall. The comment under each line is
-- a sentence that could be made by each pattern. These help me streamline the generation by
-- reminding me quickly what types of words should fit into each category.
patternArray[1]=productArray[rand(table.getn(productArray))]..", "..artArray[rand(table.getn(artArray))].." "..advArray[rand(table.getn(advArray))].." "..adjArray[rand(table.getn(adjArray))].." "..nitemArray[rand(table.getn(nitemArray))].."."
--Spiral Note, a very nice note.
patternArray[2]=artArray[rand(table.getn(artArray))].." "..naliveArray[rand(table.getn(naliveArray))].." "..vitempastArray[rand(table.getn(vitempastArray))].." "..artArray[rand(table.getn(artArray))].." "..nitemArray[rand(table.getn(nitemArray))].."."
--The boy ate a banana.
patternArray[3]=interArray[rand(table.getn(interArray))].." "..nameArray[rand(table.getn(nameArray))].." "..copulaArray[rand(table.getn(copulaArray))].." "..vitemprogArray[rand(table.getn(vitemprogArray))].." "..prepArray[rand(table.getn(prepArray))].." "..nemotionArray[rand(table.getn(nemotionArray))].." "..advArray[rand(table.getn(advArray))].."."
--Oh my god! Tim Tim is eating bananas quickly.
patternArray[4]=pleaseArray[rand(table.getn(pleaseArray))].." "..vitemArray[rand(table.getn(vitemArray))].." "..nitemArray[rand(table.getn(nitemArray))].." "..advArray[rand(table.getn(advArray))]..". "..pronArray[rand(table.getn(pronArray))].." "..copulaArray[rand(table.getn(copulaArray))].." "..adjArray[rand(table.getn(adjArray))].."."
--Please read book well. It is nice.
patternArray[5]=pronArray[rand(table.getn(pronArray))].." "..copulaArray[rand(table.getn(copulaArray))].." "..vprogArray[rand(table.getn(vprogArray))].." "..prepArray[rand(table.getn(prepArray))].." "..vprogArray[rand(table.getn(vprogArray))].."."
--We are coming for bowling.
patternArray[6]=pronArray[rand(table.getn(pronArray))].." "..copulaArray[rand(table.getn(copulaArray))].." "..nameArray[rand(table.getn(nameArray))]..". "..adjArray[rand(table.getn(adjArray))].." "..prepArray[rand(table.getn(prepArray))].." "..vprogArray[rand(table.getn(vprogArray))].." "..pronArray[rand(table.getn(pronArray))].."."
--I am Miffy. Nice to meeting you.
patternArray[7]=pronArray[rand(table.getn(pronArray))].." "..nemotionArray[rand(table.getn(nemotionArray))].." "..possArray[rand(table.getn(possArray))].." "..adjArray[rand(table.getn(adjArray))].." "..productArray[rand(table.getn(productArray))].."."
--I love my wonderful SPIRAL NOTE.
patternArray[8]=pronArray[rand(table.getn(pronArray))].." "..copulaArray[rand(table.getn(copulaArray))].." "..compArray[rand(table.getn(compArray))].." "..naliveArray[rand(table.getn(naliveArray))]..". "..suggArray[rand(table.getn(suggArray))].." "..vArray[rand(table.getn(vArray))].." "..artArray[rand(table.getn(artArray))].." "..timeArray[rand(table.getn(timeArray))].." "..advArray[rand(table.getn(advArray))].."."
--We are best friends. Let's spend the day together.
patternArray[9]=artArray[rand(table.getn(artArray))].." "..nitemArray[rand(table.getn(nitemArray))].." "..copulaArray[rand(table.getn(copulaArray))].." "..vitempastArray[rand(table.getn(vitempastArray))].." "..prepArray[rand(table.getn(prepArray))].." "..artArray[rand(table.getn(artArray))].." "..adjArray[rand(table.getn(adjArray))].." "..nemotionArray[rand(table.getn(nemotionArray))].."."
--This item is made for the good looks.
patternArray[10]=pronArray[rand(table.getn(pronArray))].." "..copulaArray[rand(table.getn(copulaArray))].." "..vprogArray[rand(table.getn(vprogArray))].." "..clauseArray[rand(table.getn(clauseArray))].." "..artArray[rand(table.getn(artArray))].." "..nitemArray[rand(table.getn(nitemArray))].." "..copulaArray[rand(table.getn(copulaArray))].." "..adjArray[rand(table.getn(adjArray))].."."
--I'm going where the air is free.
patternArray[11]=suggArray[rand(table.getn(suggArray))].." "..vArray[rand(table.getn(vArray))].." "..artArray[rand(table.getn(artArray))].." "..nabstrArray[rand(table.getn(nabstrArray))].." "..prepArray[rand(table.getn(prepArray))].." "..artArray[rand(table.getn(artArray))].." "..nthingArray[rand(table.getn(nthingArray))].."."
--Let's take a ride on the highway.
patternArray[12]=nameArray[rand(table.getn(nameArray))].." "..copulaArray[rand(table.getn(copulaArray))].." "..adjArray[rand(table.getn(adjArray))].." "..prepArray[rand(table.getn(prepArray))].." "..adjArray[rand(table.getn(adjArray))].." "..timeArray[rand(table.getn(timeArray))].."."
--Miffy is nostalgic on rainy days.

if pad:up() and oldpad:up() ~= pad:up() then
-- Here's my pattern being randomly selected and assigned to a temporary variable holder. I have also added
-- in a second holder to take the old value and preserve it till another sentence is created.
toggle = true
backuppattern = thispattern
thispattern = patternArray[rand(table.getn(patternArray))]
screen:clear()
main()
screen:print(20,40,thispattern,green)
-- For some reason, having this in my main loop outside of an event causes flickering. Anyone
-- else have this problem? The tutorials I read suggested otherwise, so I was pretty happy when
-- I finally figured out that I could stop the flickering my placing my screen.flips in my events. 
screen.flip()
end

-- This is for going back a sentence. I want to allow the program to toggle back and forth between
-- the current and the last generated one, but for some reason there is a problem with changing from
-- the old sentence, back to the current one. I think it is a flipping problem, but it might be my
-- long list of conditions.
if pad:down() and oldpad:down() ~= pad:down() and thispattern ~= nil and toggle == false then
toggle = true
screen:clear()
main()
screen:print(20,40,thispattern,green)
screen.flip()
end

if pad:down() and oldpad:down() ~= pad:down() and backuppattern ~= nil and toggle == true then
toggle = false
screen:clear()
main()
screen:print(20,40,backuppattern,grey)
screen.flip()
end

-- Can't see something that's not there.
if pad:down() and oldpad:down() ~= pad:down() and backuppattern == nil then
screen:clear()
main()
screen:print(20,40,"Please generate 2 sentences first...",red)
screen.flip()
end

-- This saves extremely funny sentences to a file called favs.txt. It appends to the 
-- end of the file and inserts a line break before each sentence. I added in conditions to prevent
-- a line return from being inserted at the top of a blank line. I realize I could probably do this
-- with fewer lines of code, but since it works, I'd rather not take the time to change it right now. =)
if pad:right() and oldpad:right() ~= pad:right() and thispattern ~= nil and toggle == true then
favscheck = io.open ("favs.txt", "r")
favsblank = favscheck:read()
favscheck:close()
if favsblank == nil then
favs = io.open("favs.txt", "a")
favs:write(thispattern)
favs:close()
screen:clear()
main()
screen:print(20,40,"Written to favs.txt...",red)
screen:print(20,50,thispattern,green)
screen.flip()
else
favs = io.open("favs.txt", "a")
favs:write("\n"..thispattern)
favs:close()
screen:clear()
main()
screen:print(20,40,"Written to favs.txt...",red)
screen:print(20,50,thispattern,green)
screen.flip()
end
end

if pad:right() and oldpad:right() ~= pad:right() and thispattern ~= nil and toggle == false then
favscheck = io.open ("favs.txt", "r")
favsblank = favscheck:read()
favscheck:close()
if favsblank == nil then
favs = io.open("favs.txt", "a")
favs:write(backuppattern)
favs:close()
screen:clear()
main()
screen:print(20,40,"Written to favs.txt...",red)
screen:print(20,50,backuppattern,grey)
screen.flip()
else
favs = io.open("favs.txt", "a")
favs:write("\n"..backuppattern)
favs:close()
screen:clear()
main()
screen:print(20,40,"Written to favs.txt...",red)
screen:print(20,50,backuppattern,grey)
screen.flip()
end
end

-- Again, you can't write somethign that's not there.
if pad:right() and oldpad:right() ~= pad:right() and thispattern == nil then
screen:clear()
main()
screen:print(20,40,"Please generate a sentence first...",red)
screen.flip()
end

if pad:left() and oldpad:left() ~= pad:left() then
oldfav = favsread:read()
if oldfav == nil then
favsread:close()
favsread = io.open("favs.txt", "r")
screen:clear()
main()
screen:print(20,40,"End of file. Please start again.",red)
screen.flip()
else
screen:clear()
main()
screen:print(20,40,oldfav, blue)
screen.flip()
end
end

screen.waitVblankStart()
oldpad = pad

-- The end
end
favsread:close()


