#include <time.h>


#include <qvaluelist.h>
#include <qdir.h>
#include <qimage.h>
#include <qpainter.h>
#include <qtl.h>
#include <qstringlist.h>


#include <kglobal.h>
#include <kstddirs.h>
#include <kdesktopfile.h>


#include "astro.h"
#include "maploader.h"


QList<MapTheme> MapLoader::themes()
{
  QList<MapTheme> result;

  QStringList files = KGlobal::dirs()->findAllResources("data", "kworldclock/maps/*/*.desktop");
  for (QStringList::Iterator it=files.begin(); it != files.end(); ++it)
    {
      KDesktopFile conf(*it);
      conf.setGroup("Theme");
      result.append(new MapTheme(conf.readName(), conf.readEntry("Theme")));
    }

  return result;
}


QStringList MapLoader::maps(QString theme)
{
  return KGlobal::dirs()->findAllResources("data", QString("kworldclock/maps/%1/*.jpg").arg(theme));
}


void MapLoader::load(unsigned int width, QString theme, unsigned int height)
{
  // find the maps available
  QValueList<uint> sizes;
  QStringList files = maps(theme);
  for (uint i=0; i<files.count(); ++i)
    {
      QString f = files[i];
      int pos = f.findRev("/");
      if (pos >= 0)
        f = f.mid(pos+1);
      pos = f.findRev(".");
      if (pos >= 0)
        f = f.left(pos);
      sizes.append(f.toInt());
    }
  qHeapSort(sizes);

  // find the closest (bigger) size
  uint size=0;
  for (uint i=0; i<sizes.count(); ++i)
    if (sizes[i] >= width)
      {
	size = sizes[i];
	break;
      }
  
  QPixmap raw;
  if (size == 0)
    {
      raw = QPixmap(locate("data", "kworldclock/maps/depths/800.jpg"));
      size = 800;
    }
  else  
    raw = QPixmap(locate("data", QString("kworldclock/maps/%1/%2.jpg").arg(theme).arg(size)));

  QImage image = raw.convertToImage();

  if (height == 0)
    height = width/2;

  if (size != width)
    image = image.smoothScale(width, height);

  // convert to light map
  _light.convertFromImage(image);

  // calculate dark map
  QRgb rgb;
  int x,y;
  for (y=0; y<image.height(); y++)
    for(x=0; x<image.width(); x++)
      {
	rgb = image.pixel(x,y);
	image.setPixel(x,y,qRgb(qRed(rgb)/2,qGreen(rgb)/2,qBlue(rgb)/2));
      }
  _dark.convertFromImage(image);
}


QBitmap MapLoader::darkMask(int width, int height)
{
  time_t t;
  struct tm *tmp;
  double jt, sunra, sundec, sunrv, sunlong;
  short *wtab;

  QBitmap illuMask(width, height);
 
  // calculate the position of the sun
  t = time(NULL);
  tmp = gmtime(&t);
  jt = jtime(tmp);
  sunpos(jt,FALSE, &sunra, &sundec, &sunrv, &sunlong);

  int sec = tmp->tm_hour*60*60 + tmp->tm_min*60 + tmp->tm_sec;
  int gmt_position = width * sec / 86400; // note: greenwich is in the middle!

  // calculate the illuminated area
  wtab = new short[height];
  projillum(wtab,width,height,sundec);
 
  // draw illumination
  illuMask.fill(Qt::black);
  QPainter p;
  p.begin(&illuMask);
 
  int start, stop;
  int middle = width - gmt_position;
  for (int y=0; y<height; y++)
    if (wtab[y]>0)
      {
	start = middle - wtab[y];
	stop = middle + wtab[y];
	if (start < 0)
	  {
	    p.drawLine(0,y,stop,y);
	    p.drawLine(width+start,y,width,y);
	  }
	else
	  if (stop > width)
	    {
	      p.drawLine(start,y,width,y);
	      p.drawLine(0,y,stop-width,y);
	    }
	  else
	    p.drawLine(start,y,stop,y);
      }
  p.end();

  return illuMask;
}
