/*Eliza Navias-Bell, Summer 2003.
"Hello, World!" program using graphical tricks.
This should be compiled with "c++ -Wall -gstabs+ helloworld.cpp -o
helloworld -lncurses".  This turns on the warnings and gdb compilation. 
It tells the compiler to compile "helloworld.cpp" and output to
"helloworld".  It links the file to -lncurses.  This MUST BE DONE or the
compiler will generate A LOT of confusing-looking errors. */
#include <iostream> // for input/output
#include <curses.h> // for graphics
#include <unistd.h> // for sleep

const char STRING_TO_DISPLAY[14] = "HELLO, WORLD!"; //declare a constant
string and give it the value "HELLO, WORLD!"; useful later

void inc(int& color_counter)
{ //circularly INCrement the color counter (mod 6)
  color_counter++;
  if(color_counter == 7)
    color_counter = 1;
}
void addchat(const char character, int& color_counter)
{ //ADD a CHaracter with a particular ATtribute
  attron(COLOR_PAIR(color_counter)); //turn on the attribute
COLOR_PAIR(number), where number is an already defined colorpair
  addch(character); //add "character" to the window
  attroff(COLOR_PAIR(color_counter)); //turn off the attribute
COLOR_PAIR(number)
  refresh(); //refresh the window; redraw it.  THIS WON'T HAPPEN
AUTOMATICALLY!!
}
void display()
{ //the function that outputs stuff to the screen
  int color_counter, loop_counter, loop_counter2; //declare integer
variables for a color counter and two loop counters
  for(color_counter = 1; color_counter < 7; color_counter++)
  { //for each color pair, display "HELLO, WORLD!" in that color
    attron(COLOR_PAIR(color_counter)); //turn on the attribute
COLOR_PAIR(number)
    move(10, 35); //move the cursor to position (10, 35) in the window. 
10 is the row counted from the top of the window and 35 is the colomn
counted from the left.
    addstr(STRING_TO_DISPLAY); //add a string ("HELLO, WORLD!") to the window
    refresh(); //refresh the window
    sleep(1); //"sleep" for 1 second; pause so that the display can be
seen by humans
    attroff(COLOR_PAIR(color_counter)); //turn off the attribute
COLOR_PAIR(number)
  }
  color_counter = 1;
  for(loop_counter = 1; loop_counter < 10; loop_counter++)
  { //display the string 10 times, with each character a different color
    move(10, 35);
    for(loop_counter2 = 0; loop_counter2 < 13; loop_counter2 ++)
    { //for each character in the string (there are 13 of them) add a
character to the screen with the next color.
      addchat(STRING_TO_DISPLAY[loop_counter2], color_counter); //add the
character in position "loop_counter2" in the string, with the
attribute that corresponds to "color_counter", to the window
      inc(color_counter); //increment the color counter
    }
    refresh();
    usleep(500000); //"sleep" for 500,000 microseconds (half a second)
  }
  init_pair(1, COLOR_BLACK, COLOR_RED);
    //initialize a color pair named 1: black character, red background
(the inverse of the original definition, which it replaces)
  init_pair(2, COLOR_BLACK, COLOR_BLUE);
    //initialize a color pair named 2: black character, blue background
  init_pair(3, COLOR_BLACK, COLOR_GREEN);
    //initialize a color pair named 3: black character, green background
  init_pair(4, COLOR_BLACK, COLOR_YELLOW);
    //initialize a color pair named 4: black character, yellow background
  init_pair(5, COLOR_BLACK, COLOR_MAGENTA);
    //initialize a color pair named 5: black character, magenta background
  init_pair(6, COLOR_BLACK, COLOR_CYAN);
    //initialize a color pair named 6: black character, cyan background
  for(loop_counter = 1; loop_counter < 10; loop_counter++)
  { //do the same thing as the last loop, with the reversed color definitions
    move(10, 35);
    for(loop_counter2 = 0; loop_counter2 < 13; loop_counter2 ++)
    {
      addchat(STRING_TO_DISPLAY[loop_counter2], color_counter);
      inc(color_counter);
    }
    refresh();
    usleep(500000);
  }
  //initialize another set of color pairs, with the first color being the
character color and the second being the background color.
  init_pair(1, COLOR_CYAN, COLOR_RED);
  init_pair(2, COLOR_RED, COLOR_BLUE);
  init_pair(3, COLOR_BLUE, COLOR_GREEN);
  init_pair(4, COLOR_GREEN, COLOR_YELLOW);
  init_pair(5, COLOR_YELLOW, COLOR_MAGENTA);
  init_pair(6, COLOR_MAGENTA, COLOR_CYAN);
  for(loop_counter = 1; loop_counter < 10; loop_counter++)
  { //do it again...
    move(10, 35);
    for(loop_counter2 = 0; loop_counter2 < 13; loop_counter2 ++)
    {
      addchat(STRING_TO_DISPLAY[loop_counter2], color_counter);
      inc(color_counter);
    }
    refresh();
    usleep(500000);
  }
  attron(A_NORMAL); //turn on the attribute "normal"
  move(10, 35);
  addstr("HELLO, WORLD!");
  refresh();
  sleep(1);
  attroff(A_NORMAL); //turn off the attribute "normal"
  attron(A_STANDOUT); //turn on the attribute "standout"
  move(10, 35);
  addstr("HELLO, WORLD!");
  refresh();
  sleep(1);
  attroff(A_STANDOUT); //turn off the attribute "standout"
  attron(A_UNDERLINE); //turn on the attribute "underline"
  move(10, 35);
  addstr("HELLO, WORLD!");
  refresh();
  sleep(1);
  attroff(A_UNDERLINE); //turn off the attribute "underline"
  attron(A_REVERSE); //turn on the attribute "reverse"
  move(10, 35);
  addstr("HELLO, WORLD!");
  refresh();
  sleep(1);
  attroff(A_REVERSE); //turn off the attribute "reverse"
  attron(A_BLINK); //turn on the attribute "blink"
  move(10, 35);
  addstr("HELLO, WORLD!");
  refresh();
  sleep(1);
  attroff(A_BLINK); //turn off the attribute "blink"
  attron(A_DIM); //turn on the attribute "dim"
  move(10, 35);
  addstr("HELLO, WORLD!");
  refresh();
  sleep(1);
  attroff(A_DIM); //turn off the attribute "dim"
  attron(A_BOLD); //turn on the attribute "bold"
  move(10, 35);
  addstr("HELLO, WORLD!");
  refresh();
  sleep(1);
  attroff(A_BOLD); //turn off the attribute "bold"
}
int main()
{
  initscr( ); //tells the shell to open a window
  clear( ); //clears out what's already there
  start_color( ); //turns on the color
  init_pair(1, COLOR_RED, COLOR_BLACK);
    //initialize a color pair named 1: red character, black background
  init_pair(2, COLOR_BLUE, COLOR_BLACK);
    //initialize a color pair named 2: blue character, black background
  init_pair(3, COLOR_GREEN, COLOR_BLACK);
    //initialize a color pair named 3: green character, black background
  init_pair(4, COLOR_YELLOW, COLOR_BLACK);
    //initialize a color pair named 4: yellow character, black background
  init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
    //initialize a color pair named 5: magenta character, black background
  init_pair(6, COLOR_CYAN, COLOR_BLACK);
    //initialize a color pair named 6: cyan character, black background
  cbreak( ); //disables line buffering, meaning that user input is
immediatly available to the program
  noecho( ); //don't echo the user input
  display(); //the function in this file that actually outputs stuff to
the screen
  endwin( ); //close the window (you should close all the windows you open
before exiting)
  return 0;
}

