/*
 * OpenCV application
 *
 */

#ifdef _WIN32
#include "stdafx.h"
#endif

#include "cxcore.h"    // basic OpenCV data structures
#include "cv.h"        // basic OpenCV algorithms
#include "highgui.h"   // OpenCV's (limited) display and event-handling routines
#include <cstdio>      // epic C-style I/O; feel free to change to iostream...

enum CAP_SOURCE { GET_IMAGES_FROM_CAMERA, GET_IMAGES_FROM_FILE, GET_IMAGES_FROM_VIDEO };
using namespace std;   // aargh!

// GLOBALS - there's no avoiding them in OpenCV
#ifdef _WIN32                           /* Windows  */ 
const char* IMAGES_DIRECTORY          = "..\\SetOpenCV\\setImages_v1\\";
#else                                   /* Mac OS X */
const char* IMAGES_DIRECTORY          = "../../setImages_v1/";
#endif
const char* RAW_IMAGE_NAME            = "Raw Image";
char BUFFER[1024];                      // for general-purpose strings
int  IMAGE_SOURCE                     = GET_IMAGES_FROM_CAMERA; // GET_IMAGES_FROM_FILE, GET_IMAGES_FROM_VIDEO

#include "image_handling.h"           // ensure_image_size
#include "file_handling.h"            // check_for_file
#include "pixel_access.h"             // get_rgb_pixel, set_rgb_pixel, get_gs_pixel, set_gs_pixel

// IMAGES
IplImage*   source_frame              = NULL; 
IplImage*   raw_image                 = NULL;    

// main sets everything up and runs a "grab-process-show" loop
//
int main (int argc, char * const argv[]) 
{
    
    // set up all of the windows and position them
    cvNamedWindow (RAW_IMAGE_NAME, CV_WINDOW_AUTOSIZE);         cvMoveWindow (RAW_IMAGE_NAME,20,20);
    
    CvCapture* source = cvCreateCameraCapture (CV_CAP_ANY);      // check if there is a camera available
    printf ("You %s have a camera.\n", source ? "do" : "don't"); // report the results to the console...
    
    int image_index_to_view = 0;                                 // image index to grab from IMAGES_DIRECTORY 
    
    // the "grab-process-show" loop: until 'q' or ESC is pressed ...
    //
    while (true)
    {
        
        if (source && IMAGE_SOURCE == GET_IMAGES_FROM_CAMERA)          // grab source_frame from CAMERA
        {
            source_frame = cvQueryFrame (source);                      // grab camera frame
            ensure_image_size (raw_image, source_frame, 3 );           // make sure raw_image is the same size
            cvFlip (source_frame, raw_image, 1);                       // need to flip from camera to raw_image
        }
        else                                                           // grab source_frame from FILE
        {
            strcpy (BUFFER, IMAGES_DIRECTORY);                         // print directory name to BUFFER
            sprintf (BUFFER+strlen(BUFFER),                            // then append ...
                     "image%05d.bmp", image_index_to_view);            // ... the filename
            
            if (file_is_present (BUFFER))                              // from file_handling.h
                source_frame = cvLoadImage( BUFFER );                  // grab the file if it's present
            else if (source_frame != NULL) 
                cvZero (source_frame);                                 // no file? zero out old source_frame
            else
                source_frame = cvCreateImage( cvSize(100,100), IPL_DEPTH_8U, 3);  // nothing at all? default value.
            
            ensure_image_size (raw_image, source_frame, 3 );           // make sure raw_image is the same size
            cvCopy ( source_frame, raw_image );                        // copy into raw_image
        }
        
        // show images
        cvShowImage (RAW_IMAGE_NAME, raw_image);
        
        // handle key press events - cvWaitKey is necessary to handle ALL events, as well!
        int key = cvWaitKey (10);    // 10 milliseconds of waiting, I think
        //
        if (key == 'q' || key == 'Q' || key == 27)    // quit the application, key 27 is ESC
        {
            break;
        }
        if (key == 'f' || key == 'F' )                // save the image to file
        {
            strcpy (BUFFER, IMAGES_DIRECTORY);        // directory
            strcat (BUFFER, "img.bmp");               // plus filename
            cvSaveImage (BUFFER, raw_image);          // saves it
            printf ("Image saved in %s\n", BUFFER);
        }
        if (key == 's' || key == 'S' )                // switch the image source
        {
            IMAGE_SOURCE = (GET_IMAGES_FROM_CAMERA == IMAGE_SOURCE) ? GET_IMAGES_FROM_FILE : GET_IMAGES_FROM_CAMERA;
            printf("Switching to IMAGE_SOURCE %d.\n", IMAGE_SOURCE);
        }
        if (key == ' ' || key == 'B')                 // cycle forward (spacebar) or backward 'B' through the images
        {
            image_index_to_view += key == ' ' ? 1 : -1;             // add or subtract 1
            if (image_index_to_view < 0) image_index_to_view = 0;   // can't go less than 0
        }
        
        
    }  // end of the "grab-process-show" while loop
    
    // return nicely from main...
    return 0;
}
