/*************************************************************
 ** 
 ** library.cpp
 **
 **   Created : May 20 2008 
 **        by : Varol Okan
 ** Copyright : (c) Varol Okan
 **   License : GPL v 2.0
 **
 ** Implementation of the abstract base class Interface.
 ** 
 *************************************************************/


#include <qfileinfo.h>

#include "library.h"


// The class factories
extern "C"  jhead::JHead *createPlugin ( ) {
    return new jhead::Library;
}
extern "C" void destroyPlugin ( jhead::JHead *pDeleteMe ) {
    delete pDeleteMe;
}

#ifndef PREFIX
#define PREFIX "/usr"
#endif

namespace jhead
{

extern "C"
{
#include "../jhead.h"
}

QMutex Library::m_mutex;

Library::Library ( )
{
  // Init the data
  ResetJpgfile   ( );
}

Library::~Library ( )
{
  lock        ( );
  DiscardData ( );
  unlock      ( );
}

void Library::lock ( )
{
  m_mutex.lock ( );
}

void Library::unlock ( )
{
  m_mutex.unlock ( );
}

jhead::JHead::Info *Library::getFileInfo ( QString &qsFileName )
{
  QFileInfo fileInfo ( qsFileName );
  // Since we have static crap around we have to lock this in
  lock ( );

  // Re-sets the static buffers
  DiscardData ( );
  int iRet = -1;
  try {
    iRet  = ReadJpegFile ( qsFileName.utf8 ( ).data ( ), READ_METADATA );
  }
  catch ( ... ) { }

  Info *pInfo = NULL;
  if ( iRet )  {
    pInfo                 = new Info;
    pInfo->qsFileName     = qsFileName;
    pInfo->iWidth         = ImageInfo.Width;
    pInfo->iHeight        = ImageInfo.Height;
    pInfo->iFileSize      = (int)fileInfo.size ( ); //ImageInfo.FileSize;
    pInfo->fileDate.setTime_t ( ImageInfo.FileDateTime );
    if ( pInfo->fileDate.isValid ( ) )
         pInfo->fileDate  = fileInfo.created ( );
    if ( strlen ( ImageInfo.DateTime ) > 17 )
         pInfo->imageDate = QDateTime::fromString ( ImageInfo.DateTime, Qt::ISODate ); //"yyyy:MM:dd hh:mm:ss" );
    else
         pInfo->imageDate = pInfo->fileDate;
    pInfo->iOrientation   = ImageInfo.Orientation;
    if ( ImageInfo.Comments[0] )
      pInfo->qsComment    = QString ( ImageInfo.Comments );
    if ( ImageInfo.GpsInfoPresent )  {
      pInfo->pGPSInfo = new GPSInfo;
      pInfo->pGPSInfo->qsLat = QString ( ImageInfo.GpsLat  );
      pInfo->pGPSInfo->qsLon = QString ( ImageInfo.GpsLong );
      pInfo->pGPSInfo->qsAlt = QString ( ImageInfo.GpsAlt  );
    }

    // Here we store some further informatio
    pInfo->qsCamera       = QString ( ImageInfo.CameraMake  );
    pInfo->qsModel        = QString ( ImageInfo.CameraModel );
    pInfo->bIsColor       = ImageInfo.IsColor; // Color/bw     : Black and white
    pInfo->iFlashFlags    = ImageInfo.FlashUsed;
    pInfo->fFocalLength   = ImageInfo.FocalLength; // Focal length : %4.1fmm",(double)ImageInfo.FocalLength);
    pInfo->fDigitalZoom   = ImageInfo.DigitalZoomRatio;
    pInfo->fCCDWidth      = ImageInfo.CCDWidth;
    pInfo->fExposureTime  = ImageInfo.ExposureTime;
    pInfo->fAperture      = ImageInfo.ApertureFNumber;
    pInfo->iISOEquiv      = ImageInfo.ISOequivalent;
    pInfo->fExposureBias  = ImageInfo.ExposureBias;
    pInfo->bWhitebalance  = ImageInfo.Whitebalance;
    pInfo->iLightsource   = ImageInfo.LightSource;
    pInfo->iExposureProg  = ImageInfo.ExposureProgram;
    pInfo->iDistanceRange = ImageInfo.DistanceRange;
    pInfo->qsComment      = QString ( ImageInfo.Comments );

    if ( ( ImageInfo.ThumbnailOffset != 0 )  &&  ( ImageInfo.ThumbnailSize != 0 ) )  {
      Section_t *pExifSection = FindSection ( M_EXIF );
      QImage *pImage = NULL;
      if ( pExifSection )  {
        pImage = new QImage;
        uchar   *pThumbnail;
        pThumbnail = pExifSection->Data + ImageInfo.ThumbnailOffset + 8;
        if ( ! pImage->loadFromData ( (const uchar *)pThumbnail, ImageInfo.ThumbnailSize ) )  {
          delete pImage;
          pImage = NULL;
        }
      }
      pInfo->pThumbnail = pImage;
    }
  }
  unlock ( );

  return pInfo;
}

}; // End of namespace jhead

