#include <qstring.h>
#include <qstringlist.h>
#include <qtextstream.h>

#define URL_CONV_TOUTF8   true
#define URL_CONV_FROMUTF8 false

static QByteArray __convertPercentEncoding(const QByteArray& data, const QByteArray& ex, const bool& flags)
{
  if (flags == URL_CONV_FROMUTF8)
  {
    QString s_data = QString::fromUtf8(QByteArray::fromPercentEncoding(data));
    return s_data.toLocal8Bit().toPercentEncoding(ex);
  }
  else
  {
    QString s_data = QString::fromLocal8Bit(QByteArray::fromPercentEncoding(data));
    return s_data.toUtf8().toPercentEncoding(ex);
  }  
}

//
// An input is assumed to be a percent encoded url.
// flags: URL_CONV_FROMUTF8: utf8 to local8bit
//        URL_CONV_TOUTF8: local8bit to utf8
static QByteArray __urlLocaleConverter(const QByteArray& e_url, const bool flags, const QString applied_scheme = "")
{
   // QTextStream out(stdout);
   QString a = QString::fromUtf8(e_url);
   
   // start to decompose the url to each component.
   int pos = a.indexOf(":/");
   if (pos < 0) // no scheme, the data sould not be percentencoded.
   {
      // out << "no scheme" << e_url << "\n";
      if (flags == URL_CONV_FROMUTF8)
         return QString::fromUtf8(e_url).toLocal8Bit();
      else
         return QString::fromLocal8Bit(e_url).toUtf8();
   }
   
   if ((!applied_scheme.isEmpty()) && !a.startsWith(applied_scheme))
      return e_url;
   
   QString a_scheme, a_host, a_path;
   a_scheme = a.mid(0, pos + 2);
   a.remove(0, pos + 2);
   if (!a.startsWith("/")) // a relative path, currently ignore it.
     return e_url;
   
   a.remove(0, 1);
   if (a.startsWith("/")) // no host part, a path only
     a_path = a;
   else
   {
     pos = a.indexOf("/");
     if (pos < 0)         // a host name only, no path part.
       a_host = a;
     else
     {
       a_host = a.mid(0, pos);
       a_path = a.mid(pos);
     }
   }
   
   // Convert: the host component.
   // out << a_scheme << "  ==  " << a_host << " === " << a_path << "\n";
   if ((!a_host.isEmpty()) && a_host.contains("@"))
   {
      QStringList c_1 = a_host.split("@");
      QStringList c_2 = c_1[0].split(":");
      QString r = QString::fromUtf8(__convertPercentEncoding(c_2[0].toUtf8(), "", flags));
      c_2[0] = r;
      c_1[0] = c_2.join(":");
      a_host = c_1.join("@");
   }
   // Convert: the path component.
   if (!a_path.isEmpty())
   {
      QStringList c_1 = a_path.split("#");
      QString r = QString::fromUtf8(__convertPercentEncoding(c_1[0].toUtf8(), "/", flags));
      c_1[0] = r;
      a_path = c_1.join("#");
   }
   
   // Reconstruction of our url.
   //out << a_scheme << "  ==  " << a_host << " === " << a_path << "\n";
   QByteArray res;
   res.append((a_scheme + "/").toUtf8());
   if (!a_host.isEmpty())
     res.append(a_host.toUtf8());
   if (!a_path.isEmpty())
     res.append(a_path.toUtf8());
   
   return res;
}
    
//int main(int argc, char** argv)
//{
//    QTextStream out(stdout);
//    QString sample = "¥×¥é¥â";
//    QByteArray s = sample.toUtf8().toPercentEncoding("/");
//    out << __urlLocaleConverter(sample.toUtf8(), URL_CONV_FROMUTF8) << "\n";
//    out << __urlLocaleConverter(QString("file:/").toUtf8(), URL_CONV_FROMUTF8) << "\n";
//    out << __urlLocaleConverter(QString("file:/").toUtf8() + s, URL_CONV_FROMUTF8) << "\n";
//    out << __urlLocaleConverter(QString("file://").toUtf8(), URL_CONV_FROMUTF8) << "\n";
//    out << __urlLocaleConverter(QString("file://plamo@zero").toUtf8(), URL_CONV_FROMUTF8) << "\n";
//    out << __urlLocaleConverter(QString("file://plamo@zero/").toUtf8(), URL_CONV_FROMUTF8) << "\n";
//    out << __urlLocaleConverter(QString("file://plamo@zero/").toUtf8() + s, URL_CONV_FROMUTF8) << "\n";
//    out << __urlLocaleConverter(QString("file://").toUtf8() + s + ":12345@zero/" + s, URL_CONV_FROMUTF8) << "\n";
//    out << __urlLocaleConverter(QString("file:///").toUtf8(), URL_CONV_FROMUTF8) << "\n";
//    out << __urlLocaleConverter(QString("file:///home/").toUtf8() + s, URL_CONV_FROMUTF8) << "\n";
//}
