/***************************************************************************
    smb4kbookmarkhandler  -  This class handles the bookmarks.
                             -------------------
    begin                : Fr Jan 9 2004
    copyright            : (C) 2004 by Alexander Reinholdt
    email                : dustpuppy@mail.berlios.de
 ***************************************************************************/

/***************************************************************************
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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     *
 *   General Public License for more details.                              *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,   *
 *   MA  02110-1301 USA                                                    *
 ***************************************************************************/

// TQt includes
#include <tqdir.h>
#include <tqfile.h>

// KDE includes
#include <kstandarddirs.h>
#include <kdebug.h>
#include <tdeapplication.h>

// system specific includes
#include <stdlib.h>
#include <math.h>

// application specific includes
#include "smb4kbookmarkhandler.h"
#include "smb4kdefs.h"
#include "smb4kerror.h"
#include "smb4tdeglobal.h"
#include "smb4knetworkitems.h"
#include "smb4kbookmark.h"

using namespace Smb4TDEGlobal;


Smb4KBookmarkHandler::Smb4KBookmarkHandler( TQValueList<Smb4KHostItem *> *hosts,
TQObject *parent, const char *name )
: TQObject( parent, name ), m_hosts( hosts )
{
  // First we need the directory.
  TDEStandardDirs *stddir = new TDEStandardDirs();
  TQString dir = locateLocal( "data", "smb4k", TDEGlobal::instance() );

  if ( !stddir->exists( dir ) )
  {
    stddir->makeDir( dir );
  }

  delete stddir;

  loadBookmarks();
}


Smb4KBookmarkHandler::~Smb4KBookmarkHandler()
{
  for ( TQValueList<Smb4KBookmark *>::Iterator it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it )
  {
    delete *it;
  }

  m_bookmarks.clear();

  // Do not delete m_hosts here, because it is either NULL
  // or it is handled outside of this class.
}



void Smb4KBookmarkHandler::addBookmark( Smb4KBookmark *bookmark )
{
  if ( !bookmark )
  {
    return;
  }

  if ( TQString::compare( bookmark->type(), "Printer" ) == 0 )
  {
    Smb4KError::error( ERROR_BOOKMARK_PRINTER );
    return;
  }

  if ( TQString::compare( bookmark->share(), "homes" ) == 0 )
  {
    TQString share = specifyUser( bookmark->host(), kapp->mainWidget() ? kapp->mainWidget() : 0, "SpecifyUser" );

    bookmark->setShareName( share );
  }

  // Search for the bookmark:
  Smb4KBookmark *result = findBookmarkByName( bookmark->bookmark() );

  if ( result )
  {
    if ( TQString::compare( result->workgroup().upper(), bookmark->workgroup().upper() ) == 0 )
    {
      // It's the same bookmark. We'll update it in a very
      // brutal but efficient way:
      m_bookmarks.remove( result );

      if ( result )
      {
        delete result;
      }
    }

    m_bookmarks.append( bookmark );
  }
  else
  {
    // The bookmark is new. Append it to the list:
    m_bookmarks.append( bookmark );
  }

  writeBookmarkList( m_bookmarks );
}


void Smb4KBookmarkHandler::writeBookmarkList( const TQValueList<Smb4KBookmark *> &list )
{
  if ( list != m_bookmarks )
  {
    for ( TQValueListIterator<Smb4KBookmark *> it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it )
    {
      delete *it;
    }

    m_bookmarks.clear();

    m_bookmarks = list;
  }

  TQFile file( locateLocal( "data", "smb4k/bookmarks", TDEGlobal::instance() ) );

  if ( file.open( IO_WriteOnly ) )
  {
    TQTextStream ts( &file );
    ts.setEncoding( TQTextStream::Locale );

    int serial_number = 0;

    for ( TQValueListConstIterator<Smb4KBookmark *> it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it )
    {
      if ( !(*it)->label().isEmpty() )
      {
        Smb4KBookmark *result = findBookmarkByLabel( (*it)->label() );

        if ( result &&
             (TQString::compare( result->bookmark().upper(), (*it)->bookmark().upper() ) != 0 ||
             TQString::compare( result->workgroup().upper(), (*it)->workgroup().upper() ) != 0) )
        {
          Smb4KError::information( INFO_BOOKMARK_LABEL_IN_USE, (*it)->label(), (*it)->bookmark() );

          (*it)->setLabel( TQString( "%1 (%2)" ).arg( (*it)->label() ).arg( serial_number++ ) );
        }
      }

      ts << (*it)->host() << ","
         << (*it)->share() << ","
         << (*it)->workgroup() << ","
         << (*it)->ip() << ","
         << (*it)->label() << endl;
    }

    file.close();
  }
  else
  {
    Smb4KError::error( ERROR_WRITING_FILE, TQDir::currentDirPath()+"/"+file.name() );
    return;
  }

  emit bookmarksUpdated();
}


void Smb4KBookmarkHandler::loadBookmarks()
{
  TQFile file( locateLocal( "data", "smb4k/bookmarks", TDEGlobal::instance() ) );

  TQStringList contents;

  if ( file.open( IO_ReadOnly ) )
  {
    TQTextStream ts( &file );
    ts.setEncoding( TQTextStream::Locale );

    contents = TQStringList::split( '\n', ts.read(), false );

    file.close();

    for ( TQStringList::ConstIterator it = contents.begin(); it != contents.end(); ++it )
    {
      if ( (*it).startsWith( "#" ) || (*it).startsWith( "[" ) ||
         TQString::compare( (*it).stripWhiteSpace(), TQString() ) == 0 )
      {
        continue;
      }
      else
      {
        // Load old bookmark entries (prior to version 0.7.0)
        if ( ((*it).stripWhiteSpace())[0].isDigit() )
        {
          TQString bookmark = (*it).section( "=", 1, -1 ).stripWhiteSpace();
          m_bookmarks.append( new Smb4KBookmark( bookmark.section( "/", 2, 2 ).stripWhiteSpace(), bookmark.section( "/", 3, 3 ).stripWhiteSpace(), TQString(), TQString(), "Disk" ) );
        }
        else
        {
          TQString host = (*it).section( ",", 0, 0 ).stripWhiteSpace();
          TQString share = (*it).section( ",", 1, 1 ).stripWhiteSpace();
          TQString workgroup = (*it).section( ",", 2, 2 ).stripWhiteSpace();
          TQString ip = (*it).section( ",", 3, 3 ).stripWhiteSpace();
          TQString label = (*it).section( ",", 4, 4 ).stripWhiteSpace();

          m_bookmarks.append( new Smb4KBookmark( host, share, workgroup, ip, "Disk", label ) );
        }
      }
    }

    emit bookmarksUpdated();
  }
  else
  {
    if ( file.exists() )
    {
      Smb4KError::error( ERROR_READING_FILE, file.name() );
    }
    else
    {
      // Do nothing if the file does not exist.
    }
  }
}


Smb4KBookmark *Smb4KBookmarkHandler::findBookmarkByName( const TQString &bookmark )
{
  // Update the bookmarks:
  update();

  // Find the bookmark:
  TQValueListConstIterator<Smb4KBookmark *> it;

  for ( it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it )
  {
    if ( TQString::compare( (*it)->bookmark().upper(), bookmark.upper() ) == 0 )
    {
      break;
    }
  }

  return it != m_bookmarks.end() ? *it : NULL;
}


Smb4KBookmark *Smb4KBookmarkHandler::findBookmarkByLabel( const TQString &label )
{
  // Update the bookmarks:
  update();

  // Find the bookmark:
  TQValueListConstIterator<Smb4KBookmark *> it;

  for ( it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it )
  {
    if ( TQString::compare( (*it)->label().upper(), label.upper() ) == 0 )
    {
      break;
    }
  }

  return it != m_bookmarks.end() ? *it : NULL;
}


const TQValueList<Smb4KBookmark *> &Smb4KBookmarkHandler::getBookmarks()
{
  // Update the bookmarks:
  update();

  // Return the list of bookmarks:
  return m_bookmarks;
}


void Smb4KBookmarkHandler::update()
{
  // If the user didn't pass the global Smb4KHostItem list, we are not able
  // to update the bookmarks:
  if ( !m_hosts )
  {
    return;
  }

  // Search the list of hosts for new IP addresses:
  for ( TQValueList<Smb4KBookmark *>::Iterator it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it )
  {
    for ( TQValueList<Smb4KHostItem *>::ConstIterator i = m_hosts->begin(); i != m_hosts->end(); ++i )
    {
      if ( TQString::compare( (*it)->workgroup().lower(), (*i)->workgroup().lower() ) != 0 )
      {
        // Continue, if the workgroup is not the same:
        continue;
      }
      else
      {
        if ( TQString::compare( (*it)->host().lower(), (*i)->name().lower() ) != 0 )
        {
          // Continue if the host name is not the same:
          continue;
        }
        else
        {
          // Set the IP address if it changed:
          if ( !(*i)->ip().stripWhiteSpace().isEmpty() &&
               TQString::compare( (*it)->ip(), (*i)->ip() ) != 0 )
          {
            (*it)->setIP( (*i)->ip() );
          }

          break;
        }
      }
    }
  }
}

#include "smb4kbookmarkhandler.moc"
