/*
 *
 *  $Id: printmanager.cpp $
 *  Ginkgo CADx Project
 *
 *  Copyright 2008-12 MetaEmotion S.L. All rights reserved.
 *  http://ginkgo-cadx.com
 *
 *  This file is licensed under LGPL v3 license.
 *  See License.txt for details
 *
 *
 */
#include <wx/string.h>
#include <wx/checkbox.h>
#include <wx/choice.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/stattext.h>
#include <wx/checklst.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/slider.h>
#include <wx/gbsizer.h>
#include <wx/statline.h>
#include <wx/button.h>
#include <wx/statusbr.h>
#include <wx/stattext.h>
#include <wx/frame.h>
#include <wx/image.h>
#include <wx/printdlg.h>
#include <wx/dcclient.h>
#include <wx/ginkgostyle/ginkgostyle.h>

#include "printmanager.h"

#include <sstream>

#include <api/math/geometry.h>
#include <main/entorno.h>
#include <export/contracts/iimageexportcontract.h>


namespace GNC {
	namespace GCS {
		namespace Printing {
			typedef struct MemoryBitmap
			{
				unsigned long  ancho;
				unsigned long  alto;
				unsigned char* data;

				MemoryBitmap()
				{
					ancho = 0;
					alto = 0;
					data = NULL;
				}

				~MemoryBitmap()
				{
					Clear();
				}

				void Clear()
				{
					if (data != NULL) {
						delete[] data;
					}
					ancho = 0;
					alto = 0;
					data = NULL;
				}

			} MemoryBitmap;

			typedef struct TipoWizardImprimir{
				GNC::GCS::Ptr<GNC::GCS::IImageExportDelegate> m_pExportDelegate;

				//imagenes
				bool m_incluirWidgets;
				typedef GNC::GCS::IImageExportDelegate::TValorationMaps MapaMapasValoracion;
				MapaMapasValoracion m_mapasValoracion;
				int m_filas;
				int m_columnas;

				//jpeg
				int m_jpegCalidad;

				TipoWizardImprimir(){
					m_incluirWidgets = false;
					m_filas = 1;
					m_columnas = 1;
					m_jpegCalidad = 90;
				}

				~TipoWizardImprimir(){
					m_mapasValoracion.clear();
				}

			} TipoWizardImprimir;

			//se hace solo para exponer el atributo m_printingPrepared para refrescar como dios manda
			class MiPrintPreview: public wxPrintPreview
			{
			public:
				MiPrintPreview(wxPrintout* pPrintOutPreview, wxPrintout* pPrintOutPrint,wxPrintData* pPrintData): wxPrintPreview(pPrintOutPreview,pPrintOutPrint,pPrintData)
				{
				}
				~MiPrintPreview()
				{
				}

				void VolverAConsultarPaginas()
				{
					#if defined(USE_PATCHED_LIBS)
					((MiPrintPreview*) ((wxPrintPreviewBase*)(m_pimpl)))->m_printingPrepared = false;
					#endif
				}
				void InvalidarPreviewBitmap()
				{
					#if defined(USE_PATCHED_LIBS)
					if(((MiPrintPreview*) ((wxPrintPreviewBase*)(m_pimpl)))->m_previewBitmap!=NULL)
					{
						delete ((MiPrintPreview*) ((wxPrintPreviewBase*)(m_pimpl)))->m_previewBitmap;
						((MiPrintPreview*) ((wxPrintPreviewBase*)(m_pimpl)))->m_previewBitmap = NULL;
					}
					#endif
				}
			};
			//////////////////////////
			PrintManager::PrintManager(const wxString& titulo, wxPrintData* pPrintData ) : wxPrintout(titulo)
			{
				m_pPrintData = pPrintData;
				m_pDatosExportacion = NULL;
			}

			PrintManager::~PrintManager()
			{
				m_pPrintData = NULL;
				m_pDatosExportacion = NULL;
			}

			bool PrintManager::HasPage(int page)
			{
				if(m_pDatosExportacion != NULL) {
					int numberOfSlices = m_pDatosExportacion->m_pExportDelegate->GetNumberOfSlices();
					int tmpMax = numberOfSlices / (m_pDatosExportacion->m_filas* m_pDatosExportacion->m_columnas);
					if(numberOfSlices % (m_pDatosExportacion->m_filas* m_pDatosExportacion->m_columnas) != 0) {
						tmpMax++;
					}
					if(page >=1 && page <= tmpMax)
					{
						return true;
					} else {
						return false;
					}
				} else {
					return false;
				}
			}

			bool PrintManager::OnBeginDocument(int startPage, int endPage)
			{
				if (!wxPrintout::OnBeginDocument(startPage, endPage))
				{
					return false;
				}
				return true;
			}

			void PrintManager::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
			{
				if(m_pDatosExportacion != NULL) {
					int numberOfSlices = m_pDatosExportacion->m_pExportDelegate->GetNumberOfSlices();
					int tmpMax = numberOfSlices / (m_pDatosExportacion->m_filas* m_pDatosExportacion->m_columnas);
					if(numberOfSlices % (m_pDatosExportacion->m_filas* m_pDatosExportacion->m_columnas) != 0) {
						tmpMax++;
					}
					*minPage = 1;
					*maxPage = tmpMax;
					*selPageFrom = 1;
					*selPageTo = tmpMax;
				} else {
					*minPage = 1;
					*maxPage = 1;
					*selPageFrom = 1;
					*selPageTo = 1;
				}
			}

			bool PrintManager::OnPrintPage(int page){
				wxDC *dc = GetDC();
				if (dc && m_pDatosExportacion)
				{
					//adapto el layout a la orientacion
					if(this->GetLogicalPageRect().GetSize().GetWidth() > this->GetLogicalPageRect().GetSize().GetHeight()//si ancho mayor que alto
						&& m_pDatosExportacion->m_filas > m_pDatosExportacion->m_columnas)// y filas mayor que columnas se intercambian
					{
						int filasTemp = m_pDatosExportacion->m_filas;
						m_pDatosExportacion->m_filas = m_pDatosExportacion->m_columnas;
						m_pDatosExportacion->m_columnas = filasTemp;
					} else if (this->GetLogicalPageRect().GetSize().GetWidth() < this->GetLogicalPageRect().GetSize().GetHeight()//si alto mayor que ancho
						&& m_pDatosExportacion->m_filas < m_pDatosExportacion->m_columnas)// y col mayor que filas se intercambian
					{
						int filasTemp = m_pDatosExportacion->m_filas;
						m_pDatosExportacion->m_filas = m_pDatosExportacion->m_columnas;
						m_pDatosExportacion->m_columnas = filasTemp;
					}

					//calculo tamaños
					int anchuraMM, alturaMM;
					this->GetPageSizeMM(&anchuraMM,&alturaMM);
					const int offSetImages = 5 * (this->GetLogicalPageRect().GetSize().GetWidth() / anchuraMM);
					int imagen = (page-1)*m_pDatosExportacion->m_filas*m_pDatosExportacion->m_columnas;
					const int anchoTotal = this->GetLogicalPageRect().GetSize().GetWidth()- (offSetImages * m_pDatosExportacion->m_columnas) - offSetImages;
					const int altoTotal = this->GetLogicalPageRect().GetSize().GetHeight()- (offSetImages * m_pDatosExportacion->m_filas) - offSetImages;
					const int anchoImagen = anchoTotal / m_pDatosExportacion->m_columnas;
					const int altoImagen = altoTotal / m_pDatosExportacion->m_filas;

					//limpioi
					dc->SetBackground(*wxWHITE_BRUSH);
					dc->Clear();

					int numberOfSlices = m_pDatosExportacion->m_pExportDelegate->GetNumberOfSlices();

					for(int fila = 0; fila < m_pDatosExportacion->m_filas; fila++)
					{
						for(int columna = 0; columna < m_pDatosExportacion->m_columnas && imagen < numberOfSlices; columna++, imagen++)
						{
							MemoryBitmap* m_MemoryBitmap = new MemoryBitmap();
							//pasamos los datos al helper y ya tenemos la imagen en memoria
							RenderizaImagen(imagen, m_MemoryBitmap, GNC::GCS::Vector(anchoImagen, altoImagen));
							if(m_MemoryBitmap->data != NULL) {
								wxImage img(  m_MemoryBitmap->ancho, m_MemoryBitmap->alto, m_MemoryBitmap->data, true );

								if(img.IsOk()) {
									const int xImg = (anchoImagen + offSetImages) * columna + offSetImages;
									const int yImg = (altoImagen + offSetImages) * fila +offSetImages;
									dc->DrawBitmap( img, xImg, yImg );
								}
							}
							delete m_MemoryBitmap;
						}
					}

					return true;
				}
				else {
					return false;
				}
			}

			void PrintManager::SetDatosExportacion(TipoWizardImprimir* pDatosExportacion)
			{
				m_pDatosExportacion = pDatosExportacion;
			}

			void PrintManager::RenderizaImagen(int imagen, MemoryBitmap* pMemoryBitmap, const GNC::GCS::Vector& size)
			{
				if(m_pDatosExportacion->m_pExportDelegate.IsValid()){
					GNC::GCS::IImageExportDelegate::ImageType::Pointer img;
					m_pDatosExportacion->m_pExportDelegate->GetImage(img, imagen, m_pDatosExportacion->m_mapasValoracion, m_pDatosExportacion->m_incluirWidgets, size);
					pMemoryBitmap->Clear();
					if(img.IsNotNull())
					{
						GNC::GCS::IImageExportDelegate::ImageType::PixelType* pixelPointer = img->GetPixelContainer()->GetImportPointer();
						pMemoryBitmap->Clear();
						pMemoryBitmap->data = (unsigned char*) ((void*)pixelPointer);
						img->GetPixelContainer()->SetContainerManageMemory(false);
						GNC::GCS::IImageExportDelegate::ImageType::SizeType imgSize;
						imgSize = img->GetLargestPossibleRegion().GetSize();
						pMemoryBitmap->ancho = imgSize[0];
						pMemoryBitmap->alto = imgSize[1];
					}
				}
			}


			/////////////////////////////////////////////////////////
			DialogoImpresion::DialogoImpresion(wxWindow *parent, GNC::GCS::Ptr<GNC::GCS::IImageExportDelegate>& pExportContract,const wxString& titulo, wxPrintData* pPrintData):
				wxPreviewFrame(new MiPrintPreview(new GNC::GCS::Printing::PrintManager(titulo,pPrintData),new GNC::GCS::Printing::PrintManager(titulo,pPrintData),pPrintData),parent,_("Print"))
			{
				m_pPrintData = pPrintData;
				//a 300 dpi
				m_pPrintData->SetQuality(300);
				#if defined(__WXGTK__)
				m_pPrintData->SetPaperId(wxPAPER_A4);
				#endif

				//zooms
				for(int i = 10 ; i<=100; i+= 5){
					m_zooms.push_back(i);
				}
				m_zooms.push_back(110);
				m_zooms.push_back(120);
				m_zooms.push_back(150);
				m_zooms.push_back(200);
				//

				m_printManagerPreview = static_cast<PrintManager*>(m_printPreview->GetPrintout());
				m_printManagerImpresion = static_cast<PrintManager*>(m_printPreview->GetPrintoutForPrinting());

				this->SetSizeHints( wxDefaultSize, wxDefaultSize );

				wxBoxSizer* bSizer9;
				bSizer9 = new wxBoxSizer( wxVERTICAL );

				HeaderPanel* pPanelHeader = new HeaderPanel(this);
				pPanelHeader->SetToolTip(_("Print"));
				bSizer9->Add(pPanelHeader,0,wxEXPAND);

				BodyPanel* pPanelFondo = new BodyPanel(this);

				wxGridBagSizer* gbSizerPpal;
				gbSizerPpal = new wxGridBagSizer( 0, 0 );
				gbSizerPpal->AddGrowableCol( 2 );
				gbSizerPpal->AddGrowableRow( 3 );
				gbSizerPpal->SetFlexibleDirection( wxBOTH );
				gbSizerPpal->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );

				SubTitledPanel* pPanelContenido = new SubTitledPanel(pPanelFondo, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
				pPanelContenido->SetToolTip(_("Content"));
				wxBoxSizer* sizerContenido;
				sizerContenido = new wxBoxSizer( wxVERTICAL );

				m_pIncluirWidgets = new wxCheckBox( pPanelContenido, wxID_ANY, _("Include Annotations"), wxDefaultPosition, wxDefaultSize, 0 );
				sizerContenido->Add( m_pIncluirWidgets, 0, wxALL, 5 );
				m_pIncluirWidgets->SetValue(true);

				m_pTituloMapas = new wxStaticText( pPanelContenido, wxID_ANY, _("Evaluation Maps"), wxDefaultPosition, wxDefaultSize, 0 );
				m_pTituloMapas->Wrap( -1 );
				sizerContenido->Add( m_pTituloMapas, 0, wxALL, 5 );

				wxArrayString m_pMapasCheckChoices;
				m_pMapasCheck = new wxCheckListBox( pPanelContenido, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_pMapasCheckChoices, wxLB_MULTIPLE );
				sizerContenido->Add( m_pMapasCheck, 1, wxALL|wxEXPAND, 5 );

				pPanelContenido->SetSizer(sizerContenido);

				gbSizerPpal->Add( pPanelContenido, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxEXPAND );

				SubTitledPanelSeparatorV* pSepVertical = new SubTitledPanelSeparatorV(pPanelFondo);
				gbSizerPpal->Add( pSepVertical, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxEXPAND );

				SubTitledPanelSeparatorH* pSepHorizontal = new SubTitledPanelSeparatorH(pPanelFondo);
				gbSizerPpal->Add( pSepHorizontal, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxEXPAND );

				m_pPanelPrevisualizacion = new SubTitledPanel(pPanelFondo, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
				m_pPanelPrevisualizacion->SetToolTip(_("Preview"));
				wxBoxSizer* sizerPrevisualizacion;
				sizerPrevisualizacion = new wxBoxSizer( wxVERTICAL );

				m_pSizerPrevisualizacion = new wxBoxSizer( wxVERTICAL );

				sizerPrevisualizacion->Add( m_pSizerPrevisualizacion, 1, wxEXPAND );

				wxBoxSizer* sizerZoomScroll;
				sizerZoomScroll = new wxBoxSizer( wxHORIZONTAL );

				m_pLabelPagina = new wxStaticText( m_pPanelPrevisualizacion, wxID_ANY, wxT("1/8"), wxDefaultPosition, wxDefaultSize, 0 );
				m_pLabelPagina->Wrap( -1 );
				sizerZoomScroll->Add( m_pLabelPagina, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );

				m_pSliderScroll = new wxSlider( m_pPanelPrevisualizacion, wxID_ANY, 5, 0, 10, wxDefaultPosition, wxDefaultSize, wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_TOP );
				//m_pSliderScroll->SetMinSize( wxSize( 150,-1 ) );

				sizerZoomScroll->Add( m_pSliderScroll, 1, wxALL|wxEXPAND, 3 );

				wxStaticText* staticText5 = new wxStaticText( m_pPanelPrevisualizacion, wxID_ANY, _("Zoom"), wxDefaultPosition, wxDefaultSize, 0 );
				staticText5->Wrap( -1 );
				sizerZoomScroll->Add( staticText5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );

				wxArrayString m_pZoomsChoices;
				for(std::list<int>::iterator it = m_zooms.begin(); it!= m_zooms.end(); ++it)
				{
					m_pZoomsChoices.push_back(wxString::Format(wxT("%d %%"),(*it)));
				}
				m_pZooms = new wxChoice( m_pPanelPrevisualizacion, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_pZoomsChoices, 0 );
				m_pZooms->SetSelection( 0 );
				//se oculta el zoom
				m_pZooms->Hide();
				staticText5->Hide();
				//
				sizerZoomScroll->Add( m_pZooms, 0, wxALL, 5 );

				sizerPrevisualizacion->Add( sizerZoomScroll, 0, wxEXPAND, 5 );

				m_pPanelPrevisualizacion->SetSizer(sizerPrevisualizacion);

				gbSizerPpal->Add( m_pPanelPrevisualizacion, wxGBPosition( 0, 2 ), wxGBSpan( 4, 1 ), wxEXPAND );


				SubTitledPanel* pPanelOptions = new SubTitledPanel(pPanelFondo, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
				pPanelOptions->SetToolTip(_("Options"));
				wxBoxSizer* sizerOpciones;
				sizerOpciones = new wxBoxSizer( wxHORIZONTAL );

				wxStaticText* m_staticText7 = new wxStaticText( pPanelOptions, wxID_ANY, _("Images per sheet"), wxDefaultPosition, wxDefaultSize, 0 );
				m_staticText7->Wrap( -1 );
				sizerOpciones->Add( m_staticText7, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );

				wxString m_pPaginasHojaChoices[] = { wxT("1"), wxT("2"), wxT("4"), wxT("6") };
				int m_pPaginasHojaNChoices = sizeof( m_pPaginasHojaChoices ) / sizeof( wxString );
				m_pPaginasHoja = new wxChoice( pPanelOptions, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_pPaginasHojaNChoices, m_pPaginasHojaChoices, 0 );
				m_pPaginasHoja->SetSelection( 0 );
				sizerOpciones->Add( m_pPaginasHoja, 0 );

				pPanelOptions->SetSizer(sizerOpciones);

				gbSizerPpal->Add( pPanelOptions, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxEXPAND );

				pPanelFondo->SetSizer(gbSizerPpal);
				pPanelFondo->Layout();

				bSizer9->Add( pPanelFondo, 1, wxEXPAND, 5 );

				FooterPanel* pPanelBotones = new FooterPanel(this);
				wxBoxSizer* bSizer13;
				bSizer13 = new wxBoxSizer( wxHORIZONTAL );

				bSizer13->Add( 0, 0, 1, wxEXPAND, 5 );

				m_pBotonConfigurarPagina = new wxButton( pPanelBotones, wxID_ANY, _("Page Setup ..."), wxDefaultPosition, wxDefaultSize, 0 );
				m_pBotonConfigurarPagina->SetDefault();
				bSizer13->Add( m_pBotonConfigurarPagina, 0, wxRIGHT, 5 );

				m_pBotonImprimir = new wxButton( pPanelBotones, wxID_ANY, _("Print ..."), wxDefaultPosition, wxDefaultSize, 0 );
				m_pBotonImprimir->SetDefault();
				bSizer13->Add( m_pBotonImprimir, 0, wxRIGHT|wxLEFT, 5 );

				m_pBotonCancelar = new wxButton( pPanelBotones, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
				bSizer13->Add( m_pBotonCancelar, 0, wxLEFT, 5 );

				pPanelBotones->SetSizer(bSizer13);
				bSizer13->Fit(pPanelBotones);

				bSizer9->Add( pPanelBotones, 0, wxEXPAND );

				this->SetSizer( bSizer9 );
				this->SetMinSize(wxSize(900,600));
				this->SetSize(wxSize(900,600));

				Initialize();

				this->Layout();

				this->Centre( wxBOTH );

				m_pMapasCheck->Connect( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, wxCommandEventHandler( DialogoImpresion::OnCheckCapasToggled ), NULL, this );
				m_pIncluirWidgets->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DialogoImpresion::OnCheckWidgetsAnotacion ), NULL, this );

				m_pBotonConfigurarPagina->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogoImpresion::OnConfigurarPaginaClick ), NULL, this );
				m_pBotonImprimir->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogoImpresion::OnImprimirClick ), NULL, this );
				m_pBotonCancelar->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogoImpresion::OnCancelarClick ), NULL, this );

				m_pSliderScroll->Connect( wxEVT_SCROLL_TOP, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Connect( wxEVT_SCROLL_BOTTOM, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Connect( wxEVT_SCROLL_LINEUP, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Connect( wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Connect( wxEVT_SCROLL_PAGEUP, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Connect( wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Connect( wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Connect( wxEVT_SCROLL_CHANGED, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );

				m_pZooms->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DialogoImpresion::OnZoomChoice ), NULL, this );

				m_pPaginasHoja->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DialogoImpresion::OnPaginasHoja ), NULL, this );

				m_pDatosExportacion = new TipoWizardImprimir();
				
				m_pDatosExportacion->m_incluirWidgets = true;
				m_pDatosExportacion->m_pExportDelegate = pExportContract;
				//mapas...
				//pillamos los mapas
				m_pDatosExportacion->m_mapasValoracion= pExportContract->GetValorationMaps();
				if(m_pDatosExportacion->m_mapasValoracion.size() == 0) {
					m_pTituloMapas->Show(false);
					m_pMapasCheck->Show(false);
				} else {
					typedef GNC::GCS::IImageExportDelegate::TValorationMaps MapaMapasValoracion;
					for(MapaMapasValoracion::iterator it= m_pDatosExportacion->m_mapasValoracion.begin(); it!= m_pDatosExportacion->m_mapasValoracion.end(); ++it) {
						int item = m_pMapasCheck->Append(wxString::FromUTF8((*it).first.c_str()));
						m_pMapasCheck->Check(item,(*it).second);
					}
				}
				m_printManagerPreview->SetDatosExportacion(m_pDatosExportacion);
				m_printManagerImpresion->SetDatosExportacion(m_pDatosExportacion);
				RefrescarSliders();
			}

			DialogoImpresion::~DialogoImpresion()
			{
				m_pPrintData = NULL;
				if(m_pDatosExportacion != NULL)
				{
					delete m_pDatosExportacion;
					m_pDatosExportacion = NULL;
				}
				m_pMapasCheck->Disconnect( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, wxCommandEventHandler( DialogoImpresion::OnCheckCapasToggled ), NULL, this );
				m_pIncluirWidgets->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DialogoImpresion::OnCheckWidgetsAnotacion ), NULL, this );

				m_pBotonConfigurarPagina->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogoImpresion::OnConfigurarPaginaClick ), NULL, this );
				m_pBotonImprimir->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogoImpresion::OnImprimirClick ), NULL, this );
				m_pBotonCancelar->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogoImpresion::OnCancelarClick ), NULL, this );

				m_pSliderScroll->Disconnect( wxEVT_SCROLL_TOP, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Disconnect( wxEVT_SCROLL_BOTTOM, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Disconnect( wxEVT_SCROLL_LINEUP, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Disconnect( wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Disconnect( wxEVT_SCROLL_PAGEUP, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Disconnect( wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Disconnect( wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );
				m_pSliderScroll->Disconnect( wxEVT_SCROLL_CHANGED, wxScrollEventHandler( DialogoImpresion::OnScrollPage ), NULL, this );

				m_pZooms->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DialogoImpresion::OnZoomChoice ), NULL, this );

				m_pPaginasHoja->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DialogoImpresion::OnPaginasHoja ), NULL, this );
			}

			void DialogoImpresion::CreateCanvas()
			{
				
				
				#if defined(USE_PATCHED_LIBS)				
				m_previewCanvas = new wxPreviewCanvas(m_printPreview, m_pPanelPrevisualizacion,this);
				m_pSizerPrevisualizacion->Add(m_previewCanvas,1,wxEXPAND|wxALL,3);
				m_pPanelPrevisualizacion->Layout();
				#else
				m_previewCanvas = NULL;
				#warning "PRINT NOT SUPPORTED"
				#endif
			}
			void DialogoImpresion::Initialize()
			{
				
#if wxUSE_STATUSBAR
				CreateStatusBar();
#endif

				CreateCanvas();

				m_printPreview->SetCanvas(m_previewCanvas);
				m_printPreview->SetFrame(this);

				SetAutoLayout( true );

				m_windowDisabler = new wxWindowDisabler(this);

				m_printPreview->AdjustScrollbars(m_previewCanvas);
				m_previewCanvas->SetFocus();
			}


			void DialogoImpresion::RefrescarSliders()
			{

				MiPrintPreview* pPrintPreview = dynamic_cast<MiPrintPreview*>(m_printPreview);
				if(pPrintPreview!=NULL) {
					pPrintPreview->VolverAConsultarPaginas();
				}
				m_printPreview->RenderPage(1);

				//barras
				//scroll
				if(m_printPreview->GetMaxPage() == m_printPreview->GetMinPage()) {
					m_pSliderScroll->Enable(false);
					m_pLabelPagina->SetLabel(wxT("1/1"));
				} else {
					m_pSliderScroll->Enable(true);
					m_pSliderScroll->SetMin(m_printPreview->GetMinPage());
					m_pSliderScroll->SetMax(m_printPreview->GetMaxPage());
					m_pSliderScroll->SetValue(m_printPreview->GetCurrentPage());
					std::ostringstream ostr;
					ostr << m_pSliderScroll->GetValue() << "/" << m_pSliderScroll->GetMax();
					m_pLabelPagina->SetLabel(wxString::FromUTF8(ostr.str().c_str()));
				}
				//zooms
				m_pZooms->Select(18);
				SetZoom(18);
				Refresh();
			}

			void DialogoImpresion::OnConfigurarPaginaClick( wxCommandEvent& )
			{
				wxPageSetupDialogData data(*m_pPrintData);
				wxPageSetupDialog pageSetupDialog(this,&data);
				pageSetupDialog.ShowModal();

				(*m_pPrintData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
				//se refresca el preview
				m_printPreview->GetPrintDialogData().SetPrintData(*m_pPrintData);
				m_printPreview->DetermineScaling();
				MiPrintPreview* pPrintPreview = dynamic_cast<MiPrintPreview*>(m_printPreview);
				if(pPrintPreview!=NULL) {
					pPrintPreview->InvalidarPreviewBitmap();
				}
				pPrintPreview->AdjustScrollbars(m_previewCanvas);
				m_printPreview->RenderPage(m_printPreview->GetCurrentPage());
				Refresh();
			}

			void DialogoImpresion::OnImprimirClick( wxCommandEvent& )
			{
				m_printPreview->GetPrintDialogData().SetFromPage(m_printPreview->GetMinPage());
				m_printPreview->GetPrintDialogData().SetToPage(m_printPreview->GetMaxPage());
				m_printPreview->GetPrintDialogData().SetMinPage(m_printPreview->GetMinPage());
				m_printPreview->GetPrintDialogData().SetMaxPage(m_printPreview->GetMaxPage());
				m_printPreview->GetPrintDialogData().GetPrintData().SetQuality(300);
				m_printPreview->GetPrintDialogData().GetPrintData().SetPaperId(m_pPrintData->GetPaperId());
				m_printPreview->Print(true);
			}



			void DialogoImpresion::OnCancelarClick( wxCommandEvent& )
			{
				Close();
			}

			void DialogoImpresion::OnScrollPage ( wxScrollEvent& event)
			{
				GoToPage(event.GetPosition());
			}

			void DialogoImpresion::OnZoomChoice( wxCommandEvent& )
			{
				SetZoom(m_pZooms->GetSelection());
			}

			void DialogoImpresion::GoToPage(int page)
			{
				if (m_printPreview->GetPrintout()->HasPage(page))
				{
					m_printPreview->SetCurrentPage(page);

					std::ostringstream ostr;
					ostr << m_pSliderScroll->GetValue() << "/" << m_pSliderScroll->GetMax();
					m_pLabelPagina->SetLabel(wxString::FromUTF8(ostr.str().c_str()));
				}
			}

			void DialogoImpresion::SetZoom(int position)
			{
				if(position >=0 && position < (int)m_zooms.size()) {
					std::list<int>::iterator it = m_zooms.begin();
					for (std::list<int>::size_type i = 0; i < position; i++, ++it);
					int zoom = *it;
					if(zoom != m_printPreview->GetZoom()) {
						m_printPreview->SetZoom(zoom);
					}
				}
			}

			void DialogoImpresion::OnPaginasHoja( wxCommandEvent& )
			{
				switch(m_pPaginasHoja->GetSelection())
				{
				default:
				case 0://una imagen
					m_pDatosExportacion->m_filas = 1;
					m_pDatosExportacion->m_columnas = 1;
					break;
				case 1://dos
					m_pDatosExportacion->m_filas = 1;
					m_pDatosExportacion->m_columnas = 2;
					break;
				case 2://cuatro
					m_pDatosExportacion->m_filas = 2;
					m_pDatosExportacion->m_columnas = 2;
					break;
				case 3://seis
					m_pDatosExportacion->m_filas = 2;
					m_pDatosExportacion->m_columnas = 3;
					break;
				}
				RefrescarSliders();
			}

			void DialogoImpresion::OnCheckCapasToggled( wxCommandEvent&  )
			{
				for(unsigned int i = 0; i< m_pMapasCheck->GetCount(); i++) {
					std::string strTmp(m_pMapasCheck->GetString(i).ToUTF8());
					m_pDatosExportacion->m_mapasValoracion[strTmp] = m_pMapasCheck->IsChecked(i);
				}
				m_printPreview->RenderPage(m_printPreview->GetCurrentPage());
				m_previewCanvas->Refresh();
			}

			void DialogoImpresion::OnCheckWidgetsAnotacion( wxCommandEvent&  )
			{
				m_pDatosExportacion->m_incluirWidgets = m_pIncluirWidgets->IsChecked();
				m_printPreview->RenderPage(m_printPreview->GetCurrentPage());
				m_previewCanvas->Refresh();
			}
		}
	}
}
