/* 
 * Copyright (c) 2004, Niek Sanders
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *
 *     + Redistributions of source code must retain the above copyright notice, 
 *       this list of conditions and the following disclaimer.
 *     + Redistributions in binary form must reproduce the above copyright 
 *       notice, this list of conditions and the following disclaimer in the 
 *       documentation and/or other materials provided with the distribution.
 *     + Neither the name of the Rochester Institute of Technology nor the names
 *       of its contributors may be used to endorse or promote products derived 
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <ctime>
#include <cstdlib>

typedef std::pair< std::string, std::string > ElementPair; 
typedef std::vector< ElementPair > ElementsList;

enum QuestionMethod { AskSymbol, AskName };

void readElements( ElementsList& eList ) {

    eList.push_back( ElementPair( "Aluminum", 	"Al" ) );
    eList.push_back( ElementPair( "Antimony", 	"Sb" ) );
    eList.push_back( ElementPair( "Argon", 	"Ar" ) );
    eList.push_back( ElementPair( "Arsenic",	"As" ) );
    eList.push_back( ElementPair( "Barium",	"Ba" ) );
    eList.push_back( ElementPair( "Beryllium",	"Be" ) );
    eList.push_back( ElementPair( "Bismuth", 	"Bi" ) );
    eList.push_back( ElementPair( "Boron", 	"B" ) );
    eList.push_back( ElementPair( "Bromine", 	"Br" ) );
    eList.push_back( ElementPair( "Cadmium", 	"Cd" ) );
    eList.push_back( ElementPair( "Calcium", 	"Ca" ) );
    eList.push_back( ElementPair( "Carbon", 	"C" ) );
    eList.push_back( ElementPair( "Chlorine", 	"Cl" ) );
    eList.push_back( ElementPair( "Chronium", 	"Cr" ) );
    eList.push_back( ElementPair( "Cobalt", 	"Co" ) );
    eList.push_back( ElementPair( "Copper", 	"Cu" ) );
    eList.push_back( ElementPair( "Florine", 	"F" ) );
    eList.push_back( ElementPair( "Gold", 	"Au" ) );

    eList.push_back( ElementPair( "Helium", 	"He" ) );
    eList.push_back( ElementPair( "Hydrogen", 	"H" ) );
    eList.push_back( ElementPair( "Iodine", 	"I" ) );
    eList.push_back( ElementPair( "Iron", 	"Fe" ) );
    eList.push_back( ElementPair( "Krypton", 	"Kr" ) );
    eList.push_back( ElementPair( "Lead", 	"Pb" ) );
    eList.push_back( ElementPair( "Lithium", 	"Li" ) );
    eList.push_back( ElementPair( "Magnesium", 	"Mg" ) );
    eList.push_back( ElementPair( "Manganese", 	"Mn" ) );
    eList.push_back( ElementPair( "Mercury", 	"Hg" ) );
    eList.push_back( ElementPair( "Molybdenum", "Mo" ) );
    eList.push_back( ElementPair( "Neon", 	"Ne" ) );
    eList.push_back( ElementPair( "Nickel", 	"Ni" ) );
    eList.push_back( ElementPair( "Nitrogen", 	"N" ) );
    eList.push_back( ElementPair( "Oxygen", 	"O" ) );
    eList.push_back( ElementPair( "Phosphorus", "P" ) );
    eList.push_back( ElementPair( "Platinum", 	"Pt" ) );
    eList.push_back( ElementPair( "Plutonium", 	"Pu" ) );

    eList.push_back( ElementPair( "Potassium", 	"K" ) );
    eList.push_back( ElementPair( "Radium", 	"Ra" ) );
    eList.push_back( ElementPair( "Rubidium", 	"Rb" ) );
    eList.push_back( ElementPair( "Scandium", 	"Sc" ) );
    eList.push_back( ElementPair( "Selenium", 	"Se" ) );
    eList.push_back( ElementPair( "Silicon", 	"Si" ) );
    eList.push_back( ElementPair( "Silver", 	"Ag" ) );
    eList.push_back( ElementPair( "Sodium", 	"Na" ) );
    eList.push_back( ElementPair( "Strontium", 	"Sr" ) );
    eList.push_back( ElementPair( "Sulfur", 	"S" ) );
    eList.push_back( ElementPair( "Tellurium", 	"Te" ) );
    eList.push_back( ElementPair( "Tin", 	"Sn" ) );
    eList.push_back( ElementPair( "Titanium", 	"Ti" ) );
    eList.push_back( ElementPair( "Tungsten", 	"W" ) );
    eList.push_back( ElementPair( "Uranium", 	"U" ) );
    eList.push_back( ElementPair( "Vanadium", 	"V" ) );
    eList.push_back( ElementPair( "Xenon", 	"Xe" ) );
    eList.push_back( ElementPair( "Zinc", 	"Zn" ) );

}

void askQuestions( const ElementsList& eList, const QuestionMethod method ) {

    char junkInput;

    for ( ElementsList::const_iterator i = eList.begin();
          i != eList.end(); 
          ++i ) {

        if ( method == AskName ) {
            std::cout << i->first << "\t\t\t";
            std::cin >> junkInput;
            std::cout << i->second << std::endl << std::endl;
        } else {
            std::cout << i->second << "\t\t\t";
            std::cin >> junkInput;
            std::cout << i->first << std::endl << std::endl;
        }

    }

}


int main( int argc, char* argv[] ) {

    // Default method (cmd override?)
    QuestionMethod method;
    if ( argc != 2 ) {
        std::cout << "Usage: ./a.out [n|s]" << std::endl;
        exit( 0 );
    } else if ( argv[ 1 ][ 0 ] == 'n' ) {
        method = AskName;
    } else if ( argv[ 1 ][ 0 ] == 's' ) {
        method = AskSymbol;
    } else {
        std::cout << "Unknown question method." << std::endl;
        exit( 0 );
    }

    // The list of elements we are quizzing
    ElementsList elements;

    // Someday this may be driven by an external file
    readElements( elements );

    // Whee! Inefficient hack! (should permute an idx array)
    // BUG ALERT!!!! Setting the 48-bit rng to affect random_shuffle is 
    // implementation dependent. Proper way would be a RandomNumberGenerator arg
    // to random_shuffle.
    srand48( time( 0 ) );
    srand( time( 0 ) );
    std::random_shuffle( elements.begin(), elements.end() );

    // Begin the interrogation!
    askQuestions( elements, method );

}
