//--------------------------------------------------------------------
// Lesson4: Switches
//
// Yes, we're going to learn about switches.  Switches allow you to
// choose paths for which window you display.  Later, we will find
// that switches are what you write your game code in.
//
// A switch statement allows you to check variables and make decisions
// based on those actions.  Variables are names you give numbers
// whose value _varies_ over time.  If you've taken algebra, you
// know what variables are: X, Y, that kind of thing. We'll talk more
// about them very soon.
//
// A switch statement looks like this:
//
//       #switch 4:1
//
// Switches end with a RETURN or a GOTO statement.  Unlike windows, 
// switches are executed invisible to the user. You can use them to 
// manipulate things without the user ever knowing. For example a 
// user crossing over an invisible trigger in a map could set up a 
// whole cast of NPCs somewhere else in the level. At the same time 
// switches can be used to prepare things for a window, or to carry 
// out a command that was indicated by a CHOICE command. Remember, 
// switches are code, and windows are what you see in the window.  
// Let's start looking at commands that start showing you the power 
// of this FULLY OPERATIONAL scripting language!
//
// Sorry.
//
// SET
// Ah. Now we're talking.  In switches, you can SET variables.  Unlike other
// languages, you don't have to declare the variables.  All undeclared
// variables are assumed to be 0.  A variable name can be any name made out
// of letters and numbers.  You can use underscores too.  (There are ways to
// use other characters, but we'll talk about that WAY later!)  Let's stick
// to simple names for now.  In a lot of languages, you name functions (what
// we call switches and windows) starting with a capital letter, then you
// capitalize each word within.  That's called InterCaps, for Internal
// Capitals.  Apple does this a lot, with names like AppleWorks, and so on.
// Anyway, variables are usually started with lower case letters, and are
// either all lowercase, or have intercaps.  This is a dumb little style
// point, but if you use a consistent style, it helps when trying to look
// over your code.  Anyway, below we are going to SET a variable called
// "talkedToGrumpos".  Here we go!
//
// So, say you talked to Grumpos, and if you have, you can now talk to
// Fleenbot.  You could do the statement:
//        set talkedToGrumpos = 1
// Now, this variable never existed before, but now it does, and it has
// a value of 1.  Any variables that are non-zero after your APE script
// executes will still exist, and will be saved with the game's save
// file.  So, you really can't assume a variable will be zero--because
// you might have set it the last time you ran this script!
//
// Okay, you can also do computations in a SET statement. (By the way,
// set statements are also called "assignment" statements, as they assign
// a value to a variable.)
//
// Here's one where we do a computation:
//       set x = 12 * 16
//       set y = -1 * (3 - 1 + (4 / 2))
//
// We will talk about more advanced operators later.
// (Programmers, there are no bitwise operations in the language.) 
//
// You can also use variables in these expressions:
// 
//      set actualY = (yt - 1) * tileSize + yPartial
//
// Okay, now the big secret of set, is you actually don't have to use the
// word SET!  You can just do this!
//
//      x = y * z		works just fine!
//
// However, most people say that you "set" a variable when you give it a,
// value so that's why you learned about it that way first!
//
// When your program quits, you can set a variable to zero (which will
// mean it will go away and not be saved in the save game file). There
// is a command that does this explicitly: unset.  You can use unset
// to set a variable to zero:
//       unset tempX
// It's just another way to do set something to zero.
//       tempX = 0
//
// Okay, we don't just have normal variables, we also have a thing
// called an "array", which is a set of indexed related values.
// Arrays look like this:
//     A[44] = 2
// We have two sizes: A[] through D[] have 10,000 elements, so you
// can look at A[0] through A[9999].  E[] through Z[] have 256
// elements, so you can look at Q[0] through Q[99].  You can use
// variables to index arrays, but you CAN'T use equations.  To use
// a variable to index an array, enclose it in dollar signs:
//    index = index + 1
//    value = A[$index$]  
// This is very useful for checking a lot of related things in
// a row.  If you have to process a set of numbers or a set of
// events, put them in an array.  For instance, you could use
// X[] and Y[] as the coordinates of each point in a path for
// an object to travel on.
//
// Well, once you have variables, how do you check their values and
// make decisions?  It's the magic word "if".
//
// IF
// The IF command allows you to check the value of any number of things,
// and then do something based on whether those comparisons were true
// or not.
//
// This is how you use it to go somewhere else:
//      if (currentX == 10) goto 30:3
//
// Note that when doing comparisons, they must be surrounded by parentheses,
// and the test for equality is represented by TWO equals signs.  This is
// a convention from the C programming language.  (You can actually use just
// one equals sign, but two is a format nicety.)
//
// There are a number of different comparisons you can make:
//
//      if (currentX != 10) goto 30:3     // not equal
//      if (currentX > 10) goto 30:3      // greater than
//      if (currentX < 10) goto 30:3      // less than 
//      if (currentX >= 10) goto 30:3      // greater than or equal to
//      if (currentX <= 10) goto 30:3      // less than or equal to
//      if (currentX) goto 30:3           // non-zero (same as currentX != 0)
//
// You can compare multiple things in an IF statement. You can check if
// this AND that are true, and if this OR that are true.  Both things
// have to be true when you use AND, but only one of the things have
// to be true for the OR, like you'd expect.  You can also check to see
// if only one or the other are true, which is called Exclusive-OR (XOR).
//
// AND is represented by this: &&
// OR is represented by this: ||
// XOR is represented by this: ^^
//
// This may be a little confusing, so let's see some examples:
//
//      if (currentX > 16 && currentY > 16) goto 30:3
// So both of these things have to be true for you to go to that window.
//
//      if (currentX < 16 || currentX > 320) goto 30:3
// So if currentX is less than 16 OR it is greater than 320, we'll go to
// the window 30:3.
//
//      if (x < 40 ^^ y < 40) goto 30:3
// This checks to see if only x or only y is less than forty, so we'll
// only go to that window if we're in the lower left or upper right
// quadrant of an 80 x 80 space.  We won't go there if we're in the
// upper left quadrant (because they are BOTH less than 40), and we
// won't go there if we are in the lower right quadrant (because both
// x and y will not be less than forty).  Only when one of them and
// not the other one is true, will the expression be true.
//      Now, this is not often used, and there isn't even a logical
// exclusive-OR in C, but we have one, so there ya go.
// (Again, programmers, there are no bitwise operations in APE.)
//
// Now, what if you want to do something different if the comparison
// is false?  If could do a whole separate IF statement, checking
// exactly the opposite, but that is stinky.  So, we have the ELSE
// statement.
//
// ELSE
// You use else to say, if the comparison is true, do that, but
// otherwise, do this.
//
//     if (playerDied) goto 30:3      // go to player died routine
//     else counter = counter + 1     // count how long player alive
//
// Now, you can do complex code inside an if or inside an else.  All
// you have to do is enclose it with "curly brackets"--"{}".  So,
// here's if and else with the curly brackets in use.
//     if (playerDied)
//     {
//	       deathCounter = deathCounter - 1
//           dyingAnimCounter = dyingAnimCounter + 1
//           if (dyingAnimCounter > 6) dyingAnimCounter = 1
//     }
//     else
//     {
//           playerAnimCounter = playerAnimCounter + 1
//           if (playerAnimCounter > 4) playerAnimCounter = 1
//     }
//     <next statement goes here>
//
// Okay, we got a little fancy here!  Not only did we put code
// sections inside curly brackets, we put an IF statement inside
// that section.  Putting an IF inside a clause of an IF is called
// having "nested IFs".  It's like one is nesting inside the other.
// Anyway, in the above, if playerDied is non-zero, the first
// section of code will be executed.  If it IS zero, then the second
// section (the else section) will get executed.  Then execution
// continues with the <next statement> after the else.
//
// There's another different way to have a subsection of code, and
// it is very powerful.  It is called GOSUB.
//
// GOSUB
// This allows you to execute a WHOLE OTHER SWITCH, then return to
// the switch you're in a keep going.  In programming languages, this
// other section of code is called a "subroutine": a routine that is
// a small routine that is either useful to many different routines,
// useful to this routine many times, or perhaps this routine has
// gotten so big, it is hard to understand, so breaking the code into
// sensible chunks will make it WAY more understandable.
//
//  ## IMPORTANT!
//  ## There is another reason to use many subroutine switches:
//  ## Switch statements can only have 30 statements executable
//  ## in any path through them.  So, if you start counting with
//  ## the first statement in a switch, no matter what IFs are
//  ## true or what way the things are set, if there is a way
//  ## to get through that switch that executes 31 statements
//  ## before GOTOing somewhere, APE will FREAK.  So be careful
//  ## not to make routines too long.
//
// So, since a GOSUB takes you to another switch, it is the perfect 
// way to cheat that 30 statement limitation.
//
// Okay, so GOSUB:
//
//      GOSUB 30:3
//      <next statement>
//
// This will execute the switch 30:3, then return with whatever it
// changed, and execute the next statement.
//
// This is so useful and a key to programming, because it allows you
// to write useful chunks of code that every part of the program
// can use.  This also reduces bugs, because otherwise you'd have
// to copy that same section of code and paste it in every place you
// want to use it!  Now imagine if you've pasted it fifty places--and
// there's a bug in it!  Now you have FIFTY bugs in your program
// instead of one!
//
// Well, up till now, we've done GOTOs and GOSUBs to numbers.  But
// that's not very mnemonic--you have to remember what those numbers
// mean.  Soooo, we have something super-useful in Flow called the
// "define" statement.
//
// DEFINE
// This is not really a command in the language, as a command for the
// APE compiler, the thing that compiles the APE script.  It tells
// the APE compiler to do string replacements in the file before
// trying to compile it into APE code.  Let's look at how we use it:
//
//      #define POOPER		"20001"
//      #define DRAW          "10"
//
//
//      #switch POOPER:DRAW
//
// So, instead of having to type: #switch 20001:10
// we have something that's much more readable. But, the above
// defines have a problem.  Look at this:
//
//      #define POOPER		"20001"
//      #define DRAW          "10"
//      #define DRAWPOOPER    "11"
// 
//      #switch POOPER:DRAWPOOPER
//
// If I have a routine "DRAWPOOPER", DPARSE is going to find all the
// defines, then first replace "POOPER" everywhere, so we'll get:
//
//      #define POOPER		"20001"
//      #define DRAW          "10"
//      #define DRAWPOOPER    "11"     // other defines not affected
// 
//      #switch 20001:DRAW20001
//
// This is not what we want.  So, you should include weird characters
// in the define, so this doesn't accidentally happen.  You can use
// any characters you want.  Squirrel uses dollar signs.  I use
// dollar signs for string replaces, and percent signs for number
// replaces.  It doesn't matter.  All the following work:
//
// #define %POOPER             "20001"
// #define $FuncA              "10"
// #define |VALUEB|            "11"
// #define !@#$%Goop%$#@!      "String"
// #define $PLocCheck          "x = pooperX
// y = pooperY
// gosub 20001:10"
//
// It just goes until it finds a quote.  You can't have spaces in the
// name, though.  Note that when I used it to replace code, I couldn't
// use the more defines inside it--you can't have nested DEFINEs.
// AND doing macros like that can be bad.  Why?  Because you can only
// have SIXTEEN statements in a switch, so if you use a bunch of
// macros like this, you run the risk of putting in too many
// statements without know it.  So chill on that, or name them
// things like 3PLOCCHECK, so you know how many lines they introduce!
//
// TIP #1:
// Putting the defines for all your Window and Switch defines at the
// start of your file will make sure you don't accidentally define them
// with the same value.
//
// TIP #2:
// It's usually easier to replace the whole bank:entry pair with one
// define, like this:
//
// #define @PooperMain	"20001:1"
//
// TIP #3
// You can use defines to give the arrays A[] through Z[] nicer names!
// Watch this:
// #define EnemyX[	"E["
//
// Anywhere in the code APE sees something like this:
// EnemyX[1] = 1
//
// It will replace it with this:
// E[1] = 1
//
// Cool, huh?
//
// REMEMBER: DEFINEs are all done before you program is compiled.  You
// can't use them for changing things at runtime, and you can't DEFINE
// things inside other DEFINE statements!
//
// One last thing you can do in switches, which opens up the power
// of built-in commands!
//
// CONSOLE
// This allows you to issues console commands from inside your Flow
// program.  You can do things that modify the window, that modify
// the level you're in, or that do internal things.
//
// The most useful one is "echo", which sends a line of text to
// the console:
//       console "echo We are in MovePooper!"
// The echo command is exceptionally helpfull for troubleshooting 
// your APE programs. For example, if you are curious if a switch 
// is being properly called, put an echo statement in it, and when 
// you run your program, drop down the console. If you don't see it
// then you can assume that switch hasn't been called. Since the 
// console is cluttered, it helps to make echo statements stand out
// like this:
//
//       console "*|*|*| -- If you see this the switch worked! -- |*|*|*"
//
// If you want to use quotes in the echo command, use \" like this:
//       console "bind x \"invoke 1:1\""
//
// This sends the following to the console:
//       bind x "invoke 1:1"
//
// You can actually print out variables with echo, but you have to
// define them, for example: 
//
//      console "echo pooperX = %f", pooperX
// Where we wanted pooper to apper we put %f, this stands for float, 
// which is the type of the variable. Technically pooperX was an 
// interger, but since this is just an echo, overkill isn't going to 
// hurt. After the end " we put a , followed by the variable we wanted 
// to appear where %f is in the console.
// So if pooperX is equal to 3, you will see on the console:
//      pooperX = 3
// The types of variables are:
// %f - floating point number (A number with a lot of decimal places)
// %d - an interger (A whole number with no decimal places.)
// %s - A string (A varaible containing text.)
//
// You can chain several of these together at once. Let's assume the 
// following variables:
// test1 = 50
// test$ = "Hello"
// test2 = 5
// console "echo %s, I have %d jellybeans. Would you like to win %d of them?", test$, test1, test2
//
// This would display the following in the console.
//
// Hello, I have 50 jellybeans. Would you like to win 5 of them?
//
//
// You cannot put an equation in there to evaluate, only a variable.
// You also cannot directly echo an array variable So, set another 
// temp variable to the element's value, and echo that:
//
//       temp = A[$index$]
//       console "echo A[index] = %f", temp
//
// (Note: in windows, you can also print variables in BODY
// statements!  Just do this:
//       body "pooperX = %d", pooperX
// It's that easy!)
//
// Additionally as the varaible updates, so will the body statement, 
// so this can be a great way to troubleshoot a variable in your
// program.
//
// We'll list more console commands in later lessons.
//
// There's another command you can set in a window.
//
// FLAGS
// This allows you to set certain flags, determining how the
// window operates.  You use it like this:
//     flags <flagname>
//
// Here are the current usable flags you can set:
//
//     flags passive
// This creates a window with no cursor, that can't be clicked away
// with the mouse. This is good for a HUD or something you want to 
// hold infront of the user for awhile.
//
//     flags passive2D
// This creates a window with a 2D cursor, but the clicking the
// mouse STILL won't dismiss the window. This is nice for an 
// interface. That way you can control the areas of interaction 
// on the interface. For example, all the worldskill mini-games 
// are passive2D windows. 
//
// Okay, that's basically all the commands for switches.  Here's a
// simple switch, with defines, variables, and so on.  You can
// compile and load it with:
//       MAP JOEY
//       LOADAPE Lesson4
//       INVOKE 4:1
//
// Each time you INVOKE 4:1, it will print out a different saying,
// and tell you the number of the counter.
//
// On to Lesson 5, where we learn that windows are even cooler than we
// thought!
//
//

//####################################################################
// DEFINES
//####################################################################
#define %Lesson4      "4"
#define %TalkToJoe    "1"
#define %JoeSaying1   "10"
#define %JoeSaying2   "20"
#define %JoeSaying3   "30"
#define %JoeSaying4   "40"


//===================================================================
// CODE
//===================================================================
#switch %Lesson4:%TalkToJoe
joeCounter = joeCounter + 1
if (joeCounter > 4) joeCounter = 1
if (joeCounter == 1) goto %Lesson4:%JoeSaying1
else if (joeCounter == 2) goto %Lesson4:%JoeSaying2
else if (joeCounter == 3) goto %Lesson4:%JoeSaying3
else goto %Lesson4:%JoeSaying4
//-------------------------------------------------------------------
#window %Lesson4:%JoeSaying1
title "Joe"
body "ZOWIE! Joe knows the counter is %d.", joeCounter

//-------------------------------------------------------------------
#window %Lesson4:%JoeSaying2
title "Joe"
body "BOOM! Joe knows the counter is %d.", joeCounter

//-------------------------------------------------------------------
#window %Lesson4:%JoeSaying3
title "Joe"
body "WHAM! Joe knows the counter is %d.", joeCounter

//-------------------------------------------------------------------
#window %Lesson4:%JoeSaying4
title "Joe"
body "PLOP! Joe knows the counter is %d.", joeCounter



