/***************************************************************************
**
**  This file is part of SciFigs.
**
**  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 file 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; if not, write to the Free Software
**  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2009-08-26
**  Copyright: 2009-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "SciFigsGlobal.h"
#include "SciFigsPlugin.h"
#include "GraphicObject.h"
#include "GraphContent.h"
#include "PluginSettings.h"

namespace SciFigs {

  /*!
    \class SciFigsGlobal SciFigsGlobal.h
    \brief Brief description of class still missing

    Full description of class still missing
  */

  double SciFigsGlobal::_screenResolution=0.0;

  /*!
    \fn SciFigsGlobal::screenResolution()
    Screen resolution, in dot per cm (set by SciFigsGlobal())
  */

  /*!
    You must create this object to initialize the library. Application must be
    created before calling this function.
  */
  SciFigsGlobal::SciFigsGlobal()
  {
    TRACE;
    // QApplication must exist
    ASSERT(QApplication::instance());
    if(!Application::instance()->hasGui()) {
      App::log("SciFigs library requires a running X server\n");
      exit(2);
    }

    // Estimate the screen resolution
    QPaintDevice * p=qApp->desktop();
    _screenResolution=static_cast<double>(p->height())/static_cast<double>(p->heightMM())*10.0;

    // Init statics used by GraphContent (coordinate tips, paint engine,...)
    GraphContent::init();

    // Load plugins
    SciFigsPluginSettings reg;
    if(reg.hasPluginList()) {
      QStringList libs=reg.pluginList();
      if(!SciFigsPlugin::loadPlugins(libs)) {
        initPlugins(false);
      }
    } else {
      initPlugins(false);
    }
  }

  SciFigsGlobal::~SciFigsGlobal()
  {
    TRACE;
    GraphContent::clear();
    _screenResolution=0.0;
  }

  /*!
    After first installation, make sure that the plugin path point to lib install directory
    so that all plugins provided with installation package are directly available.

    Add install lib directory to search paths and search for plugins
  */
  void SciFigsGlobal::initPlugins(bool debug)
  {
    TRACE;
    QStringList paths;
    QString dll;
  #ifdef Q_OS_MAC
    dll=QString("/Library/Geopsy.org/%1/plugins")
        .arg(PackageInfo::package("SciFigs")->versionType());
  #elif defined(Q_OS_WIN)
    dll=QCoreApplication::applicationDirPath();
  #else
    const PackageInfo * info=PackageInfo::package("SciFigs");
    if(info) {
      dll=info->dllDir();
    }
  #endif
    App::log(1, tr("Adding default plugin path: %1\n").arg(dll));
    if(!dll.isEmpty()) {
      QDir d(dll);
      if(d.exists()) {
        paths << dll;
        SciFigsPluginSettings reg;
        reg.setPaths(paths);
        QStringList libs=File::getLibList(paths);
        bool ok;
        QStringList plugins=SciFigsPlugin::getPluginList(libs, ok, debug);
        reg.setPluginList(plugins);
        SciFigsPlugin::loadPlugins(plugins, debug);
      }
    }
  }

  /*!
    Draw a small footprint (for all produced images). \a w and \a h are the width and height of the
    print area. \a dotpercm is the resolution of the medium.
  */
  void SciFigsGlobal::footprint(QPainter& p, double dotpercm, int w, int h)
  {
    TRACE;
    static const QString line1("SciFigs library");
    static const QString line2("by geopsy.org");
    QRect r;
    int spacing=qRound(dotpercm*0.1);
    p.save();
    p.setOpacity(0.25);
    p.setRenderHints(QPainter::TextAntialiasing);
    QPainterPath tp;
    double factor=dotpercm/SciFigsGlobal::screenResolution();
    QFont f("Comic Sans MS", qRound(factor*10), QFont::Black, true);
    p.setFont(f);
    r=p.boundingRect(0, 0, INT_MAX, INT_MAX, 0, line1);
    tp.addText(QPoint(w-r.width()-spacing, h-r.height()+spacing) , f, line1);
    r=p.boundingRect(0, 0, INT_MAX, INT_MAX, 0, line2);
    tp.addText(QPoint(w-r.width()-spacing, h-spacing) , f, line2);
    p.setPen(Qt::gray);
    p.setBrush(Qt::white);
    p.drawPath(tp);
    p.restore();
  }

  QBitmap SciFigsGlobal::colorMask(const QPixmap& pixmap, uint blankColor)
  {
    TRACE;
    int nHeight=pixmap.height();
    int nWidth=pixmap.width();
    QBitmap pmask(nWidth, nHeight);
    if(nWidth==0 || nHeight==0) {
      return pmask;
    }
    QImage mask(nWidth, nHeight, QImage::Format_Mono);
    QImage imPixmap=pixmap.toImage();
    int nWidth8=nWidth-8;
    for(int ih=0; ih<nHeight; ih++) {
      uint * bPixmap=reinterpret_cast<uint*>(imPixmap.scanLine(ih));
      uchar * bmask=mask.scanLine(ih);
      int im=0, iw=0;
      uchar maskByte;
      while(iw<nWidth8) {
        maskByte=0;
        if(bPixmap[iw]==blankColor) maskByte+=0x80;
        if(bPixmap[iw+1]==blankColor) maskByte+=0x40;
        if(bPixmap[iw+2]==blankColor) maskByte+=0x20;
        if(bPixmap[iw+3]==blankColor) maskByte+=0x10;
        if(bPixmap[iw+4]==blankColor) maskByte+=0x08;
        if(bPixmap[iw+5]==blankColor) maskByte+=0x04;
        if(bPixmap[iw+6]==blankColor) maskByte+=0x02;
        if(bPixmap[iw+7]==blankColor) maskByte+=0x01;
        bmask[im]=maskByte;
        iw+=8;
        im++;
      }
      uchar maskBit=0x80;
      maskByte=0;
      while(iw<nWidth) {
        ASSERT(maskBit);
        if(bPixmap[iw++]==blankColor) {
          maskByte+=maskBit;
        }
        maskBit=maskBit >> 1;
      }
      bmask[im]=maskByte;
    }
    pmask=QBitmap::fromImage(mask);
    return pmask;
  }

  SciFigsPluginSettings::SciFigsPluginSettings()
  {
    _reg=&CoreApplicationPrivate::instance()->globalSettings();
    _reg->beginGroup("SciFigPlugins");
    _reg->beginGroup(PackageInfo::package("SciFigs")->versionType());
  }

} // namespace SciFigs
