/*
 * Port for usage with qt-framework and development for tdesvn
 * (C) 2005-2007 by Rajko Albrecht
 * http://tdesvn.alwins-world.de
 */
/*
 * ====================================================================
 * Copyright (c) 2002-2005 The RapidSvn Group.  All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library (in the file LGPL.txt); if not,
 * write to the Free Software Foundation, Inc., 51 Franklin St,
 * Fifth Floor, Boston, MA  02110-1301  USA
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://rapidsvn.tigris.org/.
 * ====================================================================
 */


// subversion api
#include "svn_path.h"

// apr api
#include "apr_file_io.h"

// svncpp
#include "svnqt/path.h"
#include "svnqt/pool.h"
#include "svnqt/url.h"
#include "svnqt/svnqt_defines.h"
#include "svnqt/revision.h"
#include "svnqt/exception.h"

#include <tqurl.h>

namespace svn
{
  Path::Path (const char * path)
  {
    init(TQString::FROMUTF8(path));
  }

  Path::Path (const TQString & path)
  {
    init (path);
  }

  Path::Path (const Path & path)
    : m_path(path.m_path)
  {
  }

  void
  Path::init (const TQString& path)
  {
    Pool pool;

    if (path.isEmpty()) {
      m_path = "";
    } else {
      const char * int_path = svn_path_internal_style (path.TOUTF8(), pool.pool () );
      if (Url::isValid(path) ) {
        if (!svn_path_is_uri_safe(int_path)) {
            int_path = svn_path_uri_encode(int_path,pool);
        }
      }
      m_path = TQString::FROMUTF8(int_path);
      if (Url::isValid(path) && m_path.find("@")!=-1 ) {
        /// @todo make sure that "@" is never used as revision paramter
        TQUrl uri = m_path;
        m_path = uri.path();
        m_path.replace("@","%40");
        m_path = uri.protocol()+"://"+(uri.hasUser()?uri.user()+(uri.hasPassword()?":"+uri.password():"")+"@":"")
                +uri.host()+m_path;
        if (m_path.endsWith("/")) {
            int_path = svn_path_internal_style (path.TOUTF8(), pool.pool () );
            m_path = TQString::FROMUTF8(int_path);
        }
      }
    }
  }

  bool Path::isUrl()const
  {
      return Url::isValid(m_path);
  }

  const TQString &
  Path::path () const
  {
    return m_path;
  }

  Path::operator const TQString&()const
  {
    return m_path;
  }

  TQString Path::prettyPath()const
  {
    if (!Url::isValid(m_path)) {
        return m_path;
    }
    Pool pool;
    const char * int_path = svn_path_uri_decode(m_path.TOUTF8(), pool.pool () );
    TQString _p = TQString::FROMUTF8(int_path);
    _p.replace("%40","@");
    return _p;
  }

  const TQByteArray
  Path::cstr() const
  {
    return m_path.TOUTF8();
  }

  Path&
  Path::operator=(const Path & path)
  {
    if (this == &path)
      return *this;
    m_path = path.path();
    return *this;
  }

  bool
  Path::isset () const
  {
    return m_path.length () > 0;
  }

  void
  Path::addComponent (const TQString& component)
  {
      Pool pool;

    if (Url::isValid (m_path))
    {
      const char * newPath =
          svn_path_url_add_component (m_path.TOUTF8(), component.TOUTF8(), pool);
      m_path = TQString::FROMUTF8(newPath);
    }
    else
    {
      svn_stringbuf_t * pathStringbuf =
          svn_stringbuf_create (m_path.TOUTF8(), pool);

      svn_path_add_component (pathStringbuf,
                              component.TOUTF8());

      m_path = TQString::FROMUTF8(pathStringbuf->data);
    }
  }


  void
  Path::addComponent (const char* component)
  {
    addComponent (TQString::FROMUTF8(component));
  }


  void
  Path::removeLast()
  {
    Pool pool;
    if (m_path.length()<=1) {
        m_path=TQString::FROMUTF8("");
    }
    svn_stringbuf_t*pathStringbuf=
            svn_stringbuf_create (m_path.TOUTF8(), pool);
    svn_path_remove_component(pathStringbuf);
    m_path = TQString::FROMUTF8(pathStringbuf->data);
  }

  void
  Path::split (TQString & dirpath, TQString & basename) const
  {
    Pool pool;

    const char * cdirpath;
    const char * cbasename;

    svn_path_split (prettyPath().TOUTF8(), &cdirpath, &cbasename, pool);
    dirpath = TQString::FROMUTF8(cdirpath);
    basename = TQString::FROMUTF8(cbasename);
  }


  void
  Path::split (TQString & dir, TQString & filename, TQString & ext) const
  {
    TQString basename;

    // first split path into dir and filename+ext
    split (dir, basename);

    // next search for last .
    int pos = basename.findRev(TQChar('.'));

    if (pos == -1)
    {
      filename = basename;
      ext = TQString::fromLatin1("");
    }
    else
    {
      filename = basename.left(pos);
      ext = basename.mid(pos+1);
    }
  }

  Path
  Path::getTempDir ()
  {
    const char * tempdir = 0;
    Pool pool;

    if (apr_temp_dir_get (&tempdir, pool) != APR_SUCCESS)
    {
      tempdir = 0;
    }

    return tempdir;
  }

    void
    Path::parsePeg(const TQString&pathorurl,Path&_path,svn::Revision&_peg)
    {
        const char *truepath = 0;
        svn_opt_revision_t pegr;
        svn_error_t *error = 0;
        TQByteArray _buf = pathorurl.TOUTF8();

        Pool pool;
        error = svn_opt_parse_path(&pegr, &truepath,_buf,pool);
        if (error != 0) {
            throw ClientException (error);
        }
        tqDebug("Path: %s",truepath);
        _peg = svn::Revision(&pegr);
        _path=Path(truepath);
    }

  unsigned int
  Path::length () const
  {
    return m_path.length ();
  }


  TQString
  Path::native () const
  {
    Pool pool;

    return TQString::FROMUTF8(svn_path_local_style (m_path.TOUTF8(), pool));
  }

}
