// @(#)root/gui:$Name:  $:$Id: TQMimeTypes.cxx,v 1.1 2004/07/09 09:21:24 brun Exp $
// Author: Valeri Fine   21/01/2003
/****************************************************************************
** $Id: TQMimeTypes.cxx,v 1.1 2004/07/09 09:21:24 brun Exp $
**
** Copyright (C) 2002 by Valeri Fine. Brookhaven National Laboratory.
**                                    All rights reserved.
**
** This file may be distributed under the terms of the Q Public License
** as defined by Trolltech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
*****************************************************************************/

/**************************************************************************

    This source is based on Xclass95, a Win95-looking GUI toolkit.
    Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
    Xclass95 is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    and TGMimeTypes TGMime from ROOT "gui" package
    Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. 
    All rights reserved.                                                
                                                                         
   For the licensing terms see $ROOTSYS/LICENSE.                         

**************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TQMimeTypes and TQMime                                               //
//                                                                      //
// This class handles mime types, used by browsers to map file types    //
// to applications and icons. TQMime is internally used by TQMimeType.  //
// This class does allow the Qt-base gui to get the same Mime types     //
// as ROOT mime defines                                                 //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TQMimeTypes.h"
#include "TOrdCollection.h"
#include "TSystem.h"
#include "TSystemFile.h"
#include "TDatime.h"
#include "TRegexp.h"

#include "TQtRConfig.h"

#include <qiconset.h>
#include <qpixmap.h>
#include <qfileinfo.h>

// ClassImp(TQMimeTypes)
//______________________________________________________________________________
TQMimeTypes::TQMimeTypes(const char *iconPath, const char *filename)
{
   // Create a mime type cache. Read the mime types file "filename" and
   // built a list of mime types.

   char     line[1024];
   char     mime[1024];
   char     pattern[256];
   char     icon[256];
   char     sicon[256];
   char     action[256];
   char    *s;

   fIconPath = iconPath;
   fFilename = filename;
   fChanged  = kFALSE;
   fList     = new TOrdCollection(50);

   FILE *mfp;
   mfp = fopen(filename, "r");
   if (!mfp) {
      Warning("TQMimeTypes", "error opening mime type file %s", filename);
      return;
   }

   int cnt = 0;
   while (fgets(line, 1024, mfp)) {
      s = line;
      s[strlen(line)-1] = 0;       // strip off trailing \n
      while (*s == ' ') s++;       // strip leading blanks
      if (*s == '#') continue;     // skip comments
      if (!strlen(s)) continue;    // skip empty lines

      if (*s == '[') {
         strcpy(mime, line);
         cnt = 0;
         continue;
      }
      if (!strncmp(s, "pattern", 7)) {
         if (!(s = strchr(line, '='))) {
            Error("TQMimeTypes", "malformed pattern line, = missing");
            pattern[0] = 0;
         } else {
            s++;
            s = Strip(s);
            strcpy(pattern, s);
            delete [] s;
         }
         cnt++;
      } else if (!strncmp(s, "icon", 4)) {
         if (!(s = strchr(line, '='))) {
            Error("TQMimeTypes", "malformed icon line, = missing");
            icon[0] = 0;
         } else {
            s++;
            s = Strip(s);
            char *s2;
            if ((s2 = strchr(s, ' '))) {
               *s2 = 0;
               strcpy(icon, s);
               s2++;
               s2 = Strip(s2);
               strcpy(sicon, s2);
               delete [] s2;
            } else {
               strcpy(icon, s);
               strcpy(sicon, s);
            }
            delete [] s;
         }
         cnt++;
      } else if (!strncmp(s, "action", 6)) {
         if (!(s = strchr(line, '='))) {
            Error("TQMimeTypes", "malformed action line, = missing");
            action[0] = 0;
         } else {
            s++;
            s = Strip(s);
            strcpy(action, s);
            delete [] s;
         }
         cnt++;
      }

      if (cnt == 3) {
         if (strchr(pattern, ' ')) {
            char *tmppattern = strtok(pattern, " ");
            while (tmppattern && (*tmppattern != ' ')) {
               AddType(mime, tmppattern, icon, sicon, action);
               tmppattern = strtok(0, " ");
            }
         } else {
            AddType(mime, pattern, icon, sicon, action);
         }
      }
   }

   fclose(mfp);

   fChanged = kFALSE;
}

//______________________________________________________________________________
TQMimeTypes::~TQMimeTypes()
{
   // Delete mime type pool.

   if (fChanged) SaveMimes();
   fList->Delete();
   delete fList;
}

//______________________________________________________________________________
TQMime *TQMimeTypes::Find(const char *filename) const
{
   // Given a filename find the matching mime type object.

   if (!filename) return 0;

   TString fn = filename;

   TQMime  *mime;
   TIter    next(fList);

   while ((mime = (TQMime *) next()))
      if (fn.Index(*(mime->fReg)) != kNPOS) return mime;

   return 0;
}

//______________________________________________________________________________
const QIconSet *TQMimeTypes::GetIcon(const char *filename) const
{
   // Return icon belonging to mime type of filename.
   TQMime *mime= Find(filename);
   if (mime)  return mime->fIcon;
   return 0;
}
//______________________________________________________________________________
const QIconSet *TQMimeTypes::GetIcon(const TSystemFile *filename) 
{
   // Return icon belonging to mime type of TSystemFile extension 
   const char *name = filename->GetName();
   const QIconSet *set = GetIcon(name);
   if (!set) set = AddType(filename);
   return set;
}
//______________________________________________________________________________
const QIconSet *TQMimeTypes::AddType(const TSystemFile *filename)
{
   //

   QFileInfo info(filename->GetName());
   const QPixmap *icon = fDefaultProvider.pixmap(info);
   if (!icon) return 0;

   // Add an artificial mime type to the list of mime types from the default system
   TQMime *mime = new TQMime;
   mime->fType    = "system/file";
   mime->fPattern = "*.";
   mime->fPattern += (const char *)info.extension(FALSE);
   mime->fIcon  = 0;
   mime->fIcon  = new QIconSet( QPixmap(*icon) ) ;
#ifdef R__QTWIN32
   mime->fAction  = "!%s";
#else
   mime->fAction  = "";
#endif

   mime->fReg = new TRegexp(mime->fPattern, kTRUE);

   fList->Add(mime);

   fChanged = kTRUE;
   return mime->fIcon;
}
//______________________________________________________________________________
Bool_t TQMimeTypes::GetAction(const char *filename, char *action) const
{
   // Return in action the mime action string belonging to filename.

   TQMime *mime;

   action[0] = 0;
   if ((mime = Find(filename))) {
      strcpy(action, mime->fAction.Data());
      return (strlen(action) > 0);
   }
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TQMimeTypes::GetType(const char *filename, char *type) const
{
   // Return in type the mime type belonging to filename.

   TQMime *mime;

   memset(type, 0, strlen(type));
   if ((mime = Find(filename))) {
      strcpy(type, mime->fType.Data());
      return (strlen(type) > 0);
   }
   return kFALSE;
}

//______________________________________________________________________________
void TQMimeTypes::Print(Option_t *) const
{
   // Print list of mime types.

   TQMime *m;
   TIter next(fList);

   while ((m = (TQMime *) next())) {
      printf("Type:    %s\n", m->fType.Data());
      printf("Pattern: %s\n", m->fPattern.Data());
      printf("Icon:    %p\n", m->fIcon);
      printf("Action:  %s\n", m->fAction.Data());
      printf("------------\n\n");
   }
}

//______________________________________________________________________________
void TQMimeTypes::SaveMimes()
{
   // Save mime types in user's mime type file.

   char filename[1024];
   sprintf(filename, "%s/.root.mimes", gSystem->Getenv("HOME"));

   FILE *fp = fopen(filename, "w");

   if (!fp) {
      Error("SaveMimes", "can not open %s to store mime types", filename);
      return;
   }

   TDatime dt;
   fprintf(fp, "# %s written on %s\n\n", filename, dt.AsString());

   TQMime *m;
   TIter next(fList);

   while ((m = (TQMime *) next())) {
      fprintf(fp, "%s\n",            m->fType.Data());
      fprintf(fp, "pattern = %s\n",  m->fPattern.Data());
      fprintf(fp, "icon = %p\n",    m->fIcon);
      fprintf(fp, "action = %s\n\n", m->fAction.Data());
   }

   fclose(fp);

   fChanged = kFALSE;
}

//______________________________________________________________________________
void TQMimeTypes::AddType(const char *type, const char *pattern, const char *icon,
                          const char * /*sicon*/, const char *action)
{
   // Add a mime type to the list of mime types.

   TQMime *mime = new TQMime;

   mime->fType    = type;
   mime->fPattern = pattern;
   mime->fIcon    = 0; 
   char *picnam = gSystem->Which(fIconPath.Data(),icon, kReadPermission);
   if (picnam) {
      mime->fIcon  = new QIconSet( QPixmap(picnam) ) ;
   }
   delete picnam;
   mime->fAction  = action;

   mime->fReg = new TRegexp(pattern, kTRUE);

   fList->Add(mime);

   fChanged = kTRUE;
}

//______________________________________________________________________________
TQMime::~TQMime()
{
   // Delete mime object.
   delete fIcon; fIcon = 0;
   delete fReg;
}
