// File: main.cxx
//
// Functions, including mouse functions
// (as it looked at the end of class
// on Thursday, January 29, except that 
// I fixed the indentation)
//
// CSCI 1300
// Spring 2004
//
// Karl Winklmann

#include <winbgim.h>
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <string>

using namespace std;

void draw (int _x, int _y);
void move (int& _x, int& _y, int& _dx, int& _dy);

const int WINDOW_SIZE = 512;

int main ()
{
    char inputChar;

    int x;
    int y;

    int dx;
    int dy;

    bool stopped;

    // setting up graphics window
    initwindow (WINDOW_SIZE, WINDOW_SIZE, "Events and Randomness");
    setbkcolor (LIGHTCYAN);
    setcolor (BLACK);
    cleardevice ();

    inputChar = '1'; // to trigger that case, initializing x, y, dx, dy
    stopped = false; 

    draw (10, 45);

    do
    {
        if (kbhit ())               // cout << "Events> ";
            inputChar = getch ();   // cin >> inputChar;

        if (ismouseclick (WM_LBUTTONDOWN))
        {
            x = mousex ();
            y = mousey ();
            clearmouseclick (WM_LBUTTONDOWN);
        }

        if (ismouseclick (WM_MOUSEMOVE))
        {
            cout << mousex () << "  " << mousey () << endl;
            draw (mousex (), mousey ());
            clearmouseclick (WM_MOUSEMOVE);
        }
    
        switch (inputChar)
        {
            case '1':  // set starting conditions
                x = WINDOW_SIZE / 20;
                y = WINDOW_SIZE - WINDOW_SIZE / 20;
                
                dx = rand () % 20;
                dy = - rand () % 20;

                draw (x, y);
        
                inputChar = ' ';
                break;

            case 'c': // clear the graphics window
                cleardevice ();
                break;
        
            case 's': // stops and resumes
                stopped = !stopped;
                inputChar = ' ';
                break;
        
            case 'q': // will end loop
                break;
        
        } // end of switch statement
    
        // make one step
        if (!stopped) // provided we are not in 'stopped' mode
        {
            move (x, y, dx, dy);
            draw (x, y);
            // not too fast, people like to watch this in slow motion
            // delay (100);
        }
    } 
    while (inputChar != 'q');

    return EXIT_SUCCESS;
}

void draw (int _x, int _y)
{
    setfillstyle (SOLID_FILL, RED);
    fillellipse (_x, _y, 5, 5);
    circle (_x, _y, 5);
}

void move (int& _x, int& _y, int& _dx, int& _dy)
{
    // if near the floor and still moving downward
    if (_y > WINDOW_SIZE - 10 && _dy > 0)
    _dy = -_dy + 2; // reverse direction, slow down a bit
    
    // if past the right wall and still moving right
    if (_x > WINDOW_SIZE && _dx > 0)
    _dx = -_dx + 1; // reverse direction and slow own a bit
    
    // if past the left wall and still moving left
    if (_x < 0 && _dx < 0)
    _dx = -_dx - 1; // reverse direction and slow own a bit
    
    // do the actual move, i.e., change the location
    _x += _dx + rand () % 4 ; // a little random perturbation
    _y += _dy;
          
    // gravity slowing down upward motion
    _dy++;
        
}
