#include <iostream>
#include "../MString.h"

coreutils::ZString testcast(coreutils::ZString data) {
   std::cout << "in proc: " << data << std::endl;
   return data;
}

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

   // Literal string assignment tests. 
   coreutils::MString test1 = "this is an assignment test.";
   std::cout << "char * operator=: [" << test1 << "]." << std::endl;
   test1 = "new value.";
   std::cout << "char * operator=: [" << test1 << "]." << std::endl;
   std::string test11 = "this is a test";
   coreutils::MString test12 = test11;
   std::cout << "assign from std::string: [" << test12 << "]." << std::endl;   

   coreutils::MString test2("this is another test.");
   std::cout << "assign on constructor: [" << test2 << "]." << std::endl;   

   coreutils::MString xtest;
   coreutils::MString ytest("this is a test");
   xtest = ytest;
   std::cout << "assign mstring to mstring: " << xtest << std::endl;

   // Character assignment tests.
   coreutils::MString test3;
   test3 = 'a';
   std::cout << "char operator=: [" << test3 << "]." << std::endl;   

   coreutils::ZString test7("zstring data");
   coreutils::MString test4;
   coreutils::MString test5 = test7;
   std::cout << "coreutils::MString test5 = test7: [" << test5 << "]" << std::endl;
   test4 << "this is a test." << test7;
   std::cout << "char* operator<<: [" << test4 << "]." << std::endl;   

   test4 << "another test " << 75;
   std::cout << "char* operator<<: [" << test4 << "]." << std::endl;   

   // Stream assignment capabilities.
   coreutils::MString test6;
   int number = 75;
   test6 << "Will this work? " << number << test4 << " See how this works.";
   std::cout << "streaming: [" << test6 << "]." << std::endl;
   std::string test13 = "stream from string test";
   coreutils::MString test14;
   test14 << test13;
   std::cout << "streaming from std::string: [" << test14 << "]." << std::endl;

   coreutils::MString test9("XXXXXXXXXYYYYYYYYYY");
   std::cout << "test insert: " << test9 << std::endl;
   coreutils::MString test8("zzz");
   test9.insert(test8, 9);
   test9.insert("aaaaa", 9);
   std::cout << "inserting: " << test9 << std::endl;
   test9.remove(10, 7);
   std::cout << "removing: " << test9 << std::endl;

   // Reassignments.

   coreutils::MString test10;
   std::cout << ">" << test10 << "<" << std::endl;
   test10 = "";
   std::cout << ">" << test10 << "<" << std::endl;

   // Assign from ZString tests.

   coreutils::ZString test20("This is a zstring");
   coreutils::MString test21;
   test21 = test20;
   std::cout << "mstring = zstring: [" << test21 <<  "]" << std::endl;

   coreutils::MString test22;
   test22 << test20;
   std::cout << "mstring << zstring: [" << test22 <<  "]" << std::endl;

   std::string test23 = "this is a string";
   test22 = test23;
   std::cout << "mstring = string: [" << test22 <<  "]" << std::endl;

   test22 << test23;
   std::cout << "mstring << string: [" << test22 <<  "]" << std::endl;

//   coreutils::MString test24 = std::endl;
//   std::cout << "mstring << endl: " << test24 << std::endl;

   coreutils::MString test25 = 3.14159;
   std::cout << "float: " << test25 << std::endl;

   coreutils::MString test26;
   double test27 = 4.0f;
   test26 = test27;
   std::cout << "float: " << test26 << std::endl;

   coreutils::MString test28;
   int test29 = 402;
   test28 = test29;
   std::cout << "int: " << test28 << std::endl;

   coreutils::MString test30 = "ABCDEF0123";
   std::cout << test30 << " to hex " << test30.toHex() << " from hex " << test30.toHex().fromHex() << std::endl;

   std::cout << test30 << " to lower " << test30.toLower() << std::endl;

   coreutils::MString test31 = "abcdef0123";
   std::cout << test31 << " to upper " << test31.toUpper() << std::endl;

   coreutils::MString test32 = "This is a test of converting this string to base64";
   std::cout << test32 << " to base64 " << test32.toBase64() << std::endl;

   coreutils::MString test33 = test32.toBase64();
   std::cout << test33 << " from base64 " << test33.fromBase64() << std::endl;   

   coreutils::ZString test34 = test31;
   std::cout << test31 << " to zstring " << test34 << std::endl;      

   test34 = testcast(test31);
   std::cout << test31 << " to zstring " << test34 << std::endl;      
   
   return 0;
}

