// **************************************************************************
/** @file tools.cc

@todo
   - Resolve the dependancies with dim
   - Move code to a more appropriate place
   - put stuff in namespaces
*/
// **************************************************************************
#include "tools.h"

#include <stdarg.h>

using namespace std;

string Tools::Format(const char *fmt, va_list &ap)
{
    int n=256;

    char *ret=0;
    while (1)
    {
        ret = new char[n+1];

        const int sz = vsnprintf(ret, n, fmt, ap);
        if (sz<=n)
            break;

        n *= 2;
        delete [] ret;
    };

    string str(ret);

    delete [] ret;

    return str;
}

string Tools::Form(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);

    string str = Format(fmt, ap);

    va_end(ap);

    return str;
}

// --------------------------------------------------------------------------
//
//! This is a static helper to remove leading and trailing whitespaces.
//!
//! @param buf
//!    a pointer to the char array from which the whitespaces should be
//!    removed
//!
//! @returns
//!    a std::string with the whitespaces removed from buf
//
string Tools::Trim(const string &str)
{
    // Trim Both leading and trailing spaces
    const size_t start = str.find_first_not_of(' '); // Find the first character position after excluding leading blank spaces
    const size_t end   = str.find_last_not_of(' ');  // Find the first character position from reverse af

    // if all spaces or empty return an empty string
    if (string::npos==start || string::npos==end)
        return string();

    return str.substr(start, end-start+1);
}

// --------------------------------------------------------------------------
//
//! This is a static helper to remove leading and trailing whitespaces.
//!
//! Usage example:
//!
//! \code
//!    string str = "     Dies ist ein test fuer einen ganz     langen Satz "
//!        "und ob er korrekt umgebrochen und formatiert wird. Alles "
//!        "nur ein simpler test aber trotzdem ganz wichtig.";
//!
//!    cout << setfill('-') << setw(40) << "+" << endl;
//!    while (1)
//!    {
//!        const string rc = Tools::Wrap(str, 40);
//!        if (rc.empty())
//!            break;
//!        cout << rc << endl;
//!    }
//! \endcode
//!
string Tools::Wrap(string &str, size_t width)
{
    const size_t pos = str.length()<width ? string::npos : str.find_last_of(' ', width);
    if (pos==string::npos)
    {
        const string rc = str;
        str = "";
        return rc;
    }

    const size_t indent = str.find_first_not_of(' ');

    const string rc = str.substr(0, pos);
    const size_t p2 = str.find_first_not_of(' ', pos+1);

    str = str.substr(0, indent) + str.substr(p2==string::npos ? pos+1 : p2);

    return rc;
}
