// @(#)root/gui:$Id: c44ba45210ec143ec5bf9aa1708855c60088e954 $
// Author: Fons Rademakers   18/01/98

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/
/**************************************************************************

    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.

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGMimeTypes and TGMime                                               //
//                                                                      //
// This class handles mime types, used by browsers to map file types    //
// to applications and icons. TGMime is internally used by TGMimeType.  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TGMimeTypes.h"
#include "TOrdCollection.h"
#include "TSystem.h"
#include "TDatime.h"
#include "TRegexp.h"


ClassImp(TGMimeTypes)

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

   char     line[1024]   = {0};
   char     mime[1024]   = {0};
   char     pattern[256] = {0};
   char     icon[256]    = {0};
   char     sicon[256]   = {0};
   char     action[256]  = {0};
   char    *s;

   fClient   = client;
   fFilename = filename;
   fChanged  = kFALSE;
   fList     = new TOrdCollection(50);

   FILE *mfp;
   mfp = fopen(filename, "r");
   if (!mfp) {
      Warning("TGMimeTypes", "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 (!s[0]) continue;    // skip empty lines

      if (*s == '[') {
         strlcpy(mime, line, 1024);
         cnt = 0;
         continue;
      }
      if (!strncmp(s, "pattern", 7)) {
         if (!(s = strchr(line, '='))) {
            Error("TGMimeTypes", "malformed pattern line, = missing");
            pattern[0] = 0;
         } else {
            s++;
            s = Strip(s);
            strlcpy(pattern, s, 256);
            delete [] s;
         }
         cnt++;
      } else if (!strncmp(s, "icon", 4)) {
         if (!(s = strchr(line, '='))) {
            Error("TGMimeTypes", "malformed icon line, = missing");
            icon[0] = 0;
         } else {
            s++;
            s = Strip(s);
            char *s2;
            if ((s2 = strchr(s, ' '))) {
               *s2 = 0;
               strlcpy(icon, s, 256);
               s2++;
               s2 = Strip(s2);
               strlcpy(sicon, s2, 256);
               delete [] s2;
            } else {
               strlcpy(icon, s, 256);
               strlcpy(sicon, s, 256);
            }
            delete [] s;
         }
         cnt++;
      } else if (!strncmp(s, "action", 6)) {
         if (!(s = strchr(line, '='))) {
            Error("TGMimeTypes", "malformed action line, = missing");
            action[0] = 0;
         } else {
            s++;
            s = Strip(s);
            strlcpy(action, s, 256);
            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;
}

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

   if (fChanged) SaveMimes();
   fList->Delete();
   delete fList;
}
 
//______________________________________________________________________________
TGMimeTypes::TGMimeTypes(const TGMimeTypes& gmt) :
   TObject(gmt),
   fClient(gmt.fClient),
   fFilename(gmt.fFilename),
   fChanged(gmt.fChanged),
   fList(gmt.fList)
{
   // Copy constructor
}

//______________________________________________________________________________
TGMimeTypes& TGMimeTypes::operator=(const TGMimeTypes& gmt)
{
   // Assignment operator

   if(this!=&gmt) {
      TObject::operator=(gmt);
      fClient=gmt.fClient;
      fFilename=gmt.fFilename;
      fChanged=gmt.fChanged;
      fList=gmt.fList;
   } 
   return *this;
}


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

   if (!filename) return 0;

   TString fn = filename;

   TGMime  *mime;
   TIter    next(fList);

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

   return 0;
}

//______________________________________________________________________________
const TGPicture *TGMimeTypes::GetIcon(const char *filename, Bool_t small_icon)
{
   // Return icon belonging to mime type of filename.

   TGMime *mime;
   const TGPicture *mypic = 0;

   if ((mime = Find(filename))) {
      Bool_t thumb = (mime->fType == "[thumbnail]");
      if (small_icon) {
         mypic = thumb ? fClient->GetPicture(mime->fSIcon.Data(), 32, 32) :
                         fClient->GetPicture(mime->fSIcon.Data(), 16, 16);
      } else {
         mypic = thumb ? fClient->GetPicture(mime->fIcon.Data(), 64, 64) :
                         fClient->GetPicture(mime->fIcon.Data(), 32, 32);
      }
      return mypic;
   }
   return 0;
}

//______________________________________________________________________________
Bool_t TGMimeTypes::GetAction(const char *filename, char *action)
{
   // Return in action the mime action string belonging to filename.

   TGMime *mime;

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

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

   TGMime *mime;

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

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

   TGMime *m;
   TIter next(fList);

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

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

   TString filename;
#ifdef WIN32
   filename.Form("%s\\.root.mimes", gSystem->HomeDirectory());
#else
   filename.Form("%s/.root.mimes", gSystem->HomeDirectory());
#endif

   FILE *fp = fopen(filename.Data(), "wt");

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

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

   TGMime *m;
   TIter next(fList);

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

   fclose(fp);

   fChanged = kFALSE;
}

//______________________________________________________________________________
void TGMimeTypes::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.

   TGMime *mime = new TGMime;

   mime->fType    = type;
   mime->fPattern = pattern;
   mime->fIcon    = icon;
   mime->fSIcon   = sicon;
   mime->fAction  = action;

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

   fList->AddFirst(mime);

   fChanged = kTRUE;
}

//______________________________________________________________________________
TGMime::~TGMime()
{
   // Delete mime object.

   delete fReg;
}
 TGMimeTypes.cxx:1
 TGMimeTypes.cxx:2
 TGMimeTypes.cxx:3
 TGMimeTypes.cxx:4
 TGMimeTypes.cxx:5
 TGMimeTypes.cxx:6
 TGMimeTypes.cxx:7
 TGMimeTypes.cxx:8
 TGMimeTypes.cxx:9
 TGMimeTypes.cxx:10
 TGMimeTypes.cxx:11
 TGMimeTypes.cxx:12
 TGMimeTypes.cxx:13
 TGMimeTypes.cxx:14
 TGMimeTypes.cxx:15
 TGMimeTypes.cxx:16
 TGMimeTypes.cxx:17
 TGMimeTypes.cxx:18
 TGMimeTypes.cxx:19
 TGMimeTypes.cxx:20
 TGMimeTypes.cxx:21
 TGMimeTypes.cxx:22
 TGMimeTypes.cxx:23
 TGMimeTypes.cxx:24
 TGMimeTypes.cxx:25
 TGMimeTypes.cxx:26
 TGMimeTypes.cxx:27
 TGMimeTypes.cxx:28
 TGMimeTypes.cxx:29
 TGMimeTypes.cxx:30
 TGMimeTypes.cxx:31
 TGMimeTypes.cxx:32
 TGMimeTypes.cxx:33
 TGMimeTypes.cxx:34
 TGMimeTypes.cxx:35
 TGMimeTypes.cxx:36
 TGMimeTypes.cxx:37
 TGMimeTypes.cxx:38
 TGMimeTypes.cxx:39
 TGMimeTypes.cxx:40
 TGMimeTypes.cxx:41
 TGMimeTypes.cxx:42
 TGMimeTypes.cxx:43
 TGMimeTypes.cxx:44
 TGMimeTypes.cxx:45
 TGMimeTypes.cxx:46
 TGMimeTypes.cxx:47
 TGMimeTypes.cxx:48
 TGMimeTypes.cxx:49
 TGMimeTypes.cxx:50
 TGMimeTypes.cxx:51
 TGMimeTypes.cxx:52
 TGMimeTypes.cxx:53
 TGMimeTypes.cxx:54
 TGMimeTypes.cxx:55
 TGMimeTypes.cxx:56
 TGMimeTypes.cxx:57
 TGMimeTypes.cxx:58
 TGMimeTypes.cxx:59
 TGMimeTypes.cxx:60
 TGMimeTypes.cxx:61
 TGMimeTypes.cxx:62
 TGMimeTypes.cxx:63
 TGMimeTypes.cxx:64
 TGMimeTypes.cxx:65
 TGMimeTypes.cxx:66
 TGMimeTypes.cxx:67
 TGMimeTypes.cxx:68
 TGMimeTypes.cxx:69
 TGMimeTypes.cxx:70
 TGMimeTypes.cxx:71
 TGMimeTypes.cxx:72
 TGMimeTypes.cxx:73
 TGMimeTypes.cxx:74
 TGMimeTypes.cxx:75
 TGMimeTypes.cxx:76
 TGMimeTypes.cxx:77
 TGMimeTypes.cxx:78
 TGMimeTypes.cxx:79
 TGMimeTypes.cxx:80
 TGMimeTypes.cxx:81
 TGMimeTypes.cxx:82
 TGMimeTypes.cxx:83
 TGMimeTypes.cxx:84
 TGMimeTypes.cxx:85
 TGMimeTypes.cxx:86
 TGMimeTypes.cxx:87
 TGMimeTypes.cxx:88
 TGMimeTypes.cxx:89
 TGMimeTypes.cxx:90
 TGMimeTypes.cxx:91
 TGMimeTypes.cxx:92
 TGMimeTypes.cxx:93
 TGMimeTypes.cxx:94
 TGMimeTypes.cxx:95
 TGMimeTypes.cxx:96
 TGMimeTypes.cxx:97
 TGMimeTypes.cxx:98
 TGMimeTypes.cxx:99
 TGMimeTypes.cxx:100
 TGMimeTypes.cxx:101
 TGMimeTypes.cxx:102
 TGMimeTypes.cxx:103
 TGMimeTypes.cxx:104
 TGMimeTypes.cxx:105
 TGMimeTypes.cxx:106
 TGMimeTypes.cxx:107
 TGMimeTypes.cxx:108
 TGMimeTypes.cxx:109
 TGMimeTypes.cxx:110
 TGMimeTypes.cxx:111
 TGMimeTypes.cxx:112
 TGMimeTypes.cxx:113
 TGMimeTypes.cxx:114
 TGMimeTypes.cxx:115
 TGMimeTypes.cxx:116
 TGMimeTypes.cxx:117
 TGMimeTypes.cxx:118
 TGMimeTypes.cxx:119
 TGMimeTypes.cxx:120
 TGMimeTypes.cxx:121
 TGMimeTypes.cxx:122
 TGMimeTypes.cxx:123
 TGMimeTypes.cxx:124
 TGMimeTypes.cxx:125
 TGMimeTypes.cxx:126
 TGMimeTypes.cxx:127
 TGMimeTypes.cxx:128
 TGMimeTypes.cxx:129
 TGMimeTypes.cxx:130
 TGMimeTypes.cxx:131
 TGMimeTypes.cxx:132
 TGMimeTypes.cxx:133
 TGMimeTypes.cxx:134
 TGMimeTypes.cxx:135
 TGMimeTypes.cxx:136
 TGMimeTypes.cxx:137
 TGMimeTypes.cxx:138
 TGMimeTypes.cxx:139
 TGMimeTypes.cxx:140
 TGMimeTypes.cxx:141
 TGMimeTypes.cxx:142
 TGMimeTypes.cxx:143
 TGMimeTypes.cxx:144
 TGMimeTypes.cxx:145
 TGMimeTypes.cxx:146
 TGMimeTypes.cxx:147
 TGMimeTypes.cxx:148
 TGMimeTypes.cxx:149
 TGMimeTypes.cxx:150
 TGMimeTypes.cxx:151
 TGMimeTypes.cxx:152
 TGMimeTypes.cxx:153
 TGMimeTypes.cxx:154
 TGMimeTypes.cxx:155
 TGMimeTypes.cxx:156
 TGMimeTypes.cxx:157
 TGMimeTypes.cxx:158
 TGMimeTypes.cxx:159
 TGMimeTypes.cxx:160
 TGMimeTypes.cxx:161
 TGMimeTypes.cxx:162
 TGMimeTypes.cxx:163
 TGMimeTypes.cxx:164
 TGMimeTypes.cxx:165
 TGMimeTypes.cxx:166
 TGMimeTypes.cxx:167
 TGMimeTypes.cxx:168
 TGMimeTypes.cxx:169
 TGMimeTypes.cxx:170
 TGMimeTypes.cxx:171
 TGMimeTypes.cxx:172
 TGMimeTypes.cxx:173
 TGMimeTypes.cxx:174
 TGMimeTypes.cxx:175
 TGMimeTypes.cxx:176
 TGMimeTypes.cxx:177
 TGMimeTypes.cxx:178
 TGMimeTypes.cxx:179
 TGMimeTypes.cxx:180
 TGMimeTypes.cxx:181
 TGMimeTypes.cxx:182
 TGMimeTypes.cxx:183
 TGMimeTypes.cxx:184
 TGMimeTypes.cxx:185
 TGMimeTypes.cxx:186
 TGMimeTypes.cxx:187
 TGMimeTypes.cxx:188
 TGMimeTypes.cxx:189
 TGMimeTypes.cxx:190
 TGMimeTypes.cxx:191
 TGMimeTypes.cxx:192
 TGMimeTypes.cxx:193
 TGMimeTypes.cxx:194
 TGMimeTypes.cxx:195
 TGMimeTypes.cxx:196
 TGMimeTypes.cxx:197
 TGMimeTypes.cxx:198
 TGMimeTypes.cxx:199
 TGMimeTypes.cxx:200
 TGMimeTypes.cxx:201
 TGMimeTypes.cxx:202
 TGMimeTypes.cxx:203
 TGMimeTypes.cxx:204
 TGMimeTypes.cxx:205
 TGMimeTypes.cxx:206
 TGMimeTypes.cxx:207
 TGMimeTypes.cxx:208
 TGMimeTypes.cxx:209
 TGMimeTypes.cxx:210
 TGMimeTypes.cxx:211
 TGMimeTypes.cxx:212
 TGMimeTypes.cxx:213
 TGMimeTypes.cxx:214
 TGMimeTypes.cxx:215
 TGMimeTypes.cxx:216
 TGMimeTypes.cxx:217
 TGMimeTypes.cxx:218
 TGMimeTypes.cxx:219
 TGMimeTypes.cxx:220
 TGMimeTypes.cxx:221
 TGMimeTypes.cxx:222
 TGMimeTypes.cxx:223
 TGMimeTypes.cxx:224
 TGMimeTypes.cxx:225
 TGMimeTypes.cxx:226
 TGMimeTypes.cxx:227
 TGMimeTypes.cxx:228
 TGMimeTypes.cxx:229
 TGMimeTypes.cxx:230
 TGMimeTypes.cxx:231
 TGMimeTypes.cxx:232
 TGMimeTypes.cxx:233
 TGMimeTypes.cxx:234
 TGMimeTypes.cxx:235
 TGMimeTypes.cxx:236
 TGMimeTypes.cxx:237
 TGMimeTypes.cxx:238
 TGMimeTypes.cxx:239
 TGMimeTypes.cxx:240
 TGMimeTypes.cxx:241
 TGMimeTypes.cxx:242
 TGMimeTypes.cxx:243
 TGMimeTypes.cxx:244
 TGMimeTypes.cxx:245
 TGMimeTypes.cxx:246
 TGMimeTypes.cxx:247
 TGMimeTypes.cxx:248
 TGMimeTypes.cxx:249
 TGMimeTypes.cxx:250
 TGMimeTypes.cxx:251
 TGMimeTypes.cxx:252
 TGMimeTypes.cxx:253
 TGMimeTypes.cxx:254
 TGMimeTypes.cxx:255
 TGMimeTypes.cxx:256
 TGMimeTypes.cxx:257
 TGMimeTypes.cxx:258
 TGMimeTypes.cxx:259
 TGMimeTypes.cxx:260
 TGMimeTypes.cxx:261
 TGMimeTypes.cxx:262
 TGMimeTypes.cxx:263
 TGMimeTypes.cxx:264
 TGMimeTypes.cxx:265
 TGMimeTypes.cxx:266
 TGMimeTypes.cxx:267
 TGMimeTypes.cxx:268
 TGMimeTypes.cxx:269
 TGMimeTypes.cxx:270
 TGMimeTypes.cxx:271
 TGMimeTypes.cxx:272
 TGMimeTypes.cxx:273
 TGMimeTypes.cxx:274
 TGMimeTypes.cxx:275
 TGMimeTypes.cxx:276
 TGMimeTypes.cxx:277
 TGMimeTypes.cxx:278
 TGMimeTypes.cxx:279
 TGMimeTypes.cxx:280
 TGMimeTypes.cxx:281
 TGMimeTypes.cxx:282
 TGMimeTypes.cxx:283
 TGMimeTypes.cxx:284
 TGMimeTypes.cxx:285
 TGMimeTypes.cxx:286
 TGMimeTypes.cxx:287
 TGMimeTypes.cxx:288
 TGMimeTypes.cxx:289
 TGMimeTypes.cxx:290
 TGMimeTypes.cxx:291
 TGMimeTypes.cxx:292
 TGMimeTypes.cxx:293
 TGMimeTypes.cxx:294
 TGMimeTypes.cxx:295
 TGMimeTypes.cxx:296
 TGMimeTypes.cxx:297
 TGMimeTypes.cxx:298
 TGMimeTypes.cxx:299
 TGMimeTypes.cxx:300
 TGMimeTypes.cxx:301
 TGMimeTypes.cxx:302
 TGMimeTypes.cxx:303
 TGMimeTypes.cxx:304
 TGMimeTypes.cxx:305
 TGMimeTypes.cxx:306
 TGMimeTypes.cxx:307
 TGMimeTypes.cxx:308
 TGMimeTypes.cxx:309
 TGMimeTypes.cxx:310
 TGMimeTypes.cxx:311
 TGMimeTypes.cxx:312
 TGMimeTypes.cxx:313
 TGMimeTypes.cxx:314
 TGMimeTypes.cxx:315
 TGMimeTypes.cxx:316
 TGMimeTypes.cxx:317
 TGMimeTypes.cxx:318
 TGMimeTypes.cxx:319
 TGMimeTypes.cxx:320
 TGMimeTypes.cxx:321
 TGMimeTypes.cxx:322
 TGMimeTypes.cxx:323
 TGMimeTypes.cxx:324
 TGMimeTypes.cxx:325
 TGMimeTypes.cxx:326
 TGMimeTypes.cxx:327
 TGMimeTypes.cxx:328
 TGMimeTypes.cxx:329
 TGMimeTypes.cxx:330
 TGMimeTypes.cxx:331
 TGMimeTypes.cxx:332
 TGMimeTypes.cxx:333
 TGMimeTypes.cxx:334
 TGMimeTypes.cxx:335
 TGMimeTypes.cxx:336
 TGMimeTypes.cxx:337
 TGMimeTypes.cxx:338