// Needed for input and output from/to standard streams.
#include <iostream>

// provides std::vector
#include <vector>

// provides std::random_shuffle and std::sort
#include <algorithm>

// provides std::string
#include <string>

// Import only the necessary -> that's what namespaces are good for ;-)
using std::cout;
using std::cin;
using std::endl;

// Note: main is a function that
// returns an int and takes
// an int as its first argument
// and a pointer to a pointer to a character as its second argument.
// 
// We can also say, argv is an array of pointers to character arrays.
// Or we can say, argv is an array of pointers to "strings".
//
// Note that in C, "strings" are represented as arrays of characters.
// In C++, you can #include <string> for a much more powerful solution.
//
// [[[ More about pointers in another example file. ]]]
//
int main ( int argc, char ** argv )
{

	// argc is just a number.
	std::cout << "I have " << argc << " arguments." << std::endl;

	std::vector<char*> argv_vec_char_ptr;
	std::vector<std::string> argv_vec_string;

	// We print all commandline arguments one after another.
	for ( int i = 0; i < argc; ++i )
	{
		std::cout << "argv[" << i << "]: " << argv[i] << " at " << (void*) argv[i] << std::endl;
		argv_vec_char_ptr.push_back(argv[i]);
		argv_vec_string.push_back(argv[i]);
	}
	std::cout << std::endl;

	// Do the shuffling ...
	std::random_shuffle(argv_vec_char_ptr.begin(), argv_vec_char_ptr.end());
	std::random_shuffle(argv_vec_string.begin(), argv_vec_string.end());

	// Print argv_vec_char_ptr
	for ( int i = 0; i < argc; ++i )
	{
		std::cout << "argv_vec_char_ptr[" << i << "]: " << argv_vec_char_ptr[i] << " at " << (void*) argv_vec_char_ptr[i] << std::endl;
	}
	std::cout << std::endl;
	
	// Print argv_vec_string
	for ( int i = 0; i < argc; ++i )
	{
		std::cout << "argv_vec_string[" << i << "]: " << argv_vec_string[i] << " at " << & argv_vec_string[i] << std::endl;
	}
	std::cout << std::endl;

	// Sort again...
	std::sort(argv_vec_char_ptr.begin(), argv_vec_char_ptr.end());
	std::sort(argv_vec_string.begin(), argv_vec_string.end());

	// Print argv_vec_char_ptr
	for ( int i = 0; i < argc; ++i )
	{
		std::cout << "argv_vec_char_ptr[" << i << "]: " << argv_vec_char_ptr[i] << " at " << (void*) argv_vec_char_ptr[i] << std::endl;
	}
	std::cout << std::endl;
	
	// Print argv_vec_string
	for ( int i = 0; i < argc; ++i )
	{
		std::cout << "argv_vec_string[" << i << "]: " << argv_vec_string[i] << " at " << & argv_vec_string[i] << std::endl;
	}
	std::cout << std::endl;

	return 0;
}

