//////////////////////////////////////////////////////////////////////////////
// Name:        Slideshow.cpp
// Purpose:     The class to store information for slideshow
// Author:      Alex Thuering
// Created:	26.06.2005
// RCS-ID:      $Id: Slideshow.cpp,v 1.6 2008/02/25 19:22:25 ntalex Exp $
// Copyright:   (c) Alex Thuering
// Licence:     GPL
//////////////////////////////////////////////////////////////////////////////

#include "Slideshow.h"
#include <wxSVGXML/svgxmlhelpr.h>


//////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// Slide ////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

wxSvgXmlNode* Slide::GetXML()
{
  wxSvgXmlNode* node = new wxSvgXmlNode(wxSVGXML_ELEMENT_NODE, _T("slide"));
  node->AddProperty(_T("filename"), m_filename);
  return node;
}

bool Slide::PutXML(wxSvgXmlNode* node)
{
  if (node == NULL || node->GetName() != _T("slide"))
    return false;
  
  node->GetPropVal(_T("filename"), &m_filename);
  return true;
}

//////////////////////////////////////////////////////////////////////////////
///////////////////////////////// Slideshow //////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

Slideshow::Slideshow(VideoFormat videoFormat): m_videoFormat(videoFormat)
{
#ifdef __WXMSW__
  m_duration = 1;
#else
  m_duration = 5;
#endif
}

Slideshow::Slideshow(wxSvgXmlNode* node): m_videoFormat(vfPAL), m_duration(5)
{
  PutXML(node);
}

Slideshow::~Slideshow()
{
  WX_CLEAR_ARRAY(*this)
}

wxSize Slideshow::GetResolution()
{
  if (m_videoFormat == vfNTSC)
	return wxSize(720,480);
  return wxSize(720,576); // vfPAL
}

float Slideshow::GetFPS()
{
  if (m_videoFormat == vfNTSC)
	return 29.97;
  return 25; // vfPAL 
}

wxImage Slideshow::GetThumbImage(int width, int height)
{
  wxBitmap thumbImg(width, height);
  wxMemoryDC dc;
  dc.SelectObject(thumbImg);
  dc.SetPen(wxPen(*wxBLACK,0,wxTRANSPARENT));
  dc.SetBrush(wxBrush(*wxBLACK, wxSOLID));
  dc.DrawRectangle(0, 0, width, height);
  wxImage img[3];
  for (int i=0; i<3; i++)
  {
    if ((int)Count()>i)
    {
      img[i].LoadFile((*this)[i]->GetFilename());
      float scale = (float) 3*width/4/img[i].GetWidth();
      if (scale > (float) 3*height/4/img[i].GetHeight())
        scale = (float) 3*height/4/img[i].GetHeight();
      img[i].Rescale((int) (img[i].GetWidth()*scale), (int) (img[i].GetHeight()*scale));
    }
  }
  for (int i=2; i>=0; i--)
  {
    dc.SetPen(wxPen(*wxWHITE,0,wxSOLID));
    if (img[i].Ok())
    {
      int w = img[i].GetWidth();
      int h = img[i].GetHeight();
      int x = 2;
      int y = 2;
      if (i == 1)
      {
        int w0 = img[0].GetWidth();
        int h0 = img[0].GetHeight();
        int w2 = img[2].Ok() ? img[2].GetWidth() : img[0].GetWidth();
        int h2 = img[2].Ok() ? img[2].GetHeight() : img[0].GetHeight();
        x = (width + w0 - w2)/2 - w/2;
        y = (height + h0 - h2)/2 - h/2;
      }
      else if (i == 2)
      {
        x = width - w - 2;
        y = height - h - 2;
      }
      dc.DrawBitmap(wxBitmap(img[i]), x, y);
      dc.SetBrush(wxBrush(*wxBLACK, wxTRANSPARENT));
      dc.DrawRectangle(x, y, w, h);
    }
    else
    {
      int w = img[0].GetWidth();
      int h = img[0].GetHeight();
      int x = width/2 - w/2;
      int y = height/2 - h/2;
      if (i == 2)
      {
        x = width - w - 2;
        y = height - h - 2;
      }
      dc.SetBrush(wxBrush(*wxBLACK, wxSOLID));
      dc.DrawRectangle(x, y, w, h);
    }
  }
  dc.SelectObject(wxNullBitmap);
  return thumbImg.ConvertToImage();
}

wxImage Slideshow::GetImage(int index)
{
  int width = GetResolution().GetWidth();
  int height = GetResolution().GetHeight();
  wxImage img;
  if (index < (int) Count())
    img.LoadFile((*this)[index]->GetFilename());
  if (img.GetWidth() == 0 || img.GetHeight() == 0)
    return wxImage(width, height);
  float scale = (float) width / img.GetWidth();
  if (scale > (float) height / img.GetHeight())
    scale = (float) height / img.GetHeight();
  img.Rescale((int) (img.GetWidth()*scale), (int) (img.GetHeight()*scale));
  wxImage resImg(width, height);
  int x_offset1 = (width-img.GetWidth())/2;
  int x_offset2 = width-img.GetWidth()-x_offset1;
  int y_offset = (height-img.GetHeight())/2;
  unsigned char* src = img.GetData();
  unsigned char* dst = resImg.GetData() + y_offset*3*width;
  for (int y=0; y<img.GetHeight(); y++)
  {
    dst += x_offset1*3;
    for (int x=0; x<img.GetWidth(); x++)
    {
      dst[0] = src[0];
      dst[1] = src[1];
      dst[2] = src[2];
      src+=3;
      dst+=3;
    }
    dst += x_offset2*3;
  }
  return resImg;
}

wxSvgXmlNode* Slideshow::GetXML(DVDFileType type, wxSvgXmlNode* node)
{
  if (type != DVDSTYLER_XML)
    return node;
  
  node = new wxSvgXmlNode(wxSVGXML_ELEMENT_NODE, _T("slideshow"));
  node->AddProperty(_T("videoFormat"), (m_videoFormat == vfPAL) ? _T("PAL") : _T("NTSC"));
  node->AddProperty(_T("duration"), wxString::Format(_T("%d"), m_duration));
  
  for (int i=0; i<(int)Count(); i++)
    node->AddChild((*this)[i]->GetXML());
  return node;
}

bool Slideshow::PutXML(wxSvgXmlNode* node)
{
  if (node == NULL || node->GetName() != _T("slideshow"))
    return false;
  
  wxString val;
  long lval;
  
  m_videoFormat = vfPAL;
  if (node->GetPropVal(_T("videoFormat"), &val) && val == _T("NTSC"))
    m_videoFormat = vfNTSC;
  
  m_duration = 5;
  if (node->GetPropVal(_T("duration"), &val) && val.ToLong(&lval))
    m_duration = lval;
  
  wxSvgXmlNode* child = node->GetChildren();
  while (child)
  {
    if (child->GetName() == _T("slide"))
      Add(new Slide(child));
    child = child->GetNext();
  }
  
  return true;
}
