// EcopayView.cpp : Implementierung der Klasse CEcopayView
//

#include "stdafx.h"
#include "Ecopay.h"
#include "BinFile.h"
#include "EcopayDoc.h"
#include "EcopayView.h"
#include "optimierung.h"
#include "MySQLConnector.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
using namespace std;
using namespace sql;

// CEcopayView

//IMPLEMENT_DYNCREATE(CEcopayView, CView)
IMPLEMENT_DYNCREATE(CEcopayView, CScrollView)

/*
 BEGIN_MESSAGE_MAP(CEcopayView, CView)
 // Standarddruckbefehle
 ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
 //ON_COMMAND(ID_NEUERSTECKBRIEF_SCHMETTERLING, &CEcopayView::OnNeuersteckbriefSchmetterling)
 END_MESSAGE_MAP()
 */
BEGIN_MESSAGE_MAP(CEcopayView, CScrollView)
// Standarddruckbefehle
ON_COMMAND(ID_FILE_PRINT, &CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CScrollView::OnFilePrintPreview)
//ON_COMMAND(ID_NEUERSTECKBRIEF_SCHMETTERLING, &CEcopayView::OnNeuersteckbriefSchmetterling)
ON_BN_CLICKED(IDC_BUTTON_NEU_SCHMETTERLING, CEcopayApp::OnNeuersteckbriefSchmetterling)
END_MESSAGE_MAP()

// CEcopayView-Erstellung/Zerstörung

CEcopayView::CEcopayView()
{
    // TODO: Hier Code zur Konstruktion einfügen

}

CEcopayView::~CEcopayView()
{
}

BOOL CEcopayView::PreCreateWindow( CREATESTRUCT& cs)
{
    // TODO: Ändern Sie hier die Fensterklasse oder die Darstellung, indem Sie
    //  CREATESTRUCT cs modifizieren.

    //return CView::PreCreateWindow(cs);
    return CScrollView::PreCreateWindow( cs);
}

// CEcopayView-Zeichnung
void CEcopayView::OnInitialUpdate()
{
    CScrollView::OnInitialUpdate();
    // setzen auf maximale Ansicht beim Start
    //GetParent()->ShowWindow(SW_MAXIMIZE); 
    GetParent()->ShowWindow( SW_SHOW);
    CSize sizeTotal;

    sizeTotal.cx = sizeTotal.cy = 700;
    SetScrollSizes( MM_TEXT, sizeTotal);

    // erstellen den Filterkontroll Dialog
    /*
     wndFilterKontrolleDialog.Create(IDD_FILTERKONTROLLE,0);
     wndFilterKontrolleDialog.CenterWindow(this);
     wndFilterKontrolleDialog.ShowWindow(SW_SHOW);*/
}
int konfid;
int konfigurationsInt;

void CEcopayView::OnDraw( CDC* pDC)
{
    CEcopayDoc* pDoc = GetDocument();
    ASSERT_VALID( pDoc);
    if( !pDoc)
        return;

    /*	
     CButton* btNeuSchmett = new CButton;
     RECT tmp = {50,50,150,70};
     btNeuSchmett->Create( _T("Schmetterling"), WS_VISIBLE|BS_PUSHBUTTON, tmp, this, 
     IDC_BUTTON_NEU_SCHMETTERLING);
     */

    /*
     CComboBox* pBoxOne;
     pBoxOne = new CComboBox;
     RECT rctB = {20,30,80,100};

     pBoxOne->Create( WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST,rctB,
     this, 1); 
     
     optimierung* optDlg;
     optDlg = new optimierung;
     BOOL ret = optDlg->Create(IDD_DIALOG3);
     optDlg->ShowWindow(SW_SHOW);
     */

    // TODO: Code zum Zeichnen der systemeigenen Daten hinzufügen
    /*	
     MySQLConnector *mysql = new MySQLConnector();
     
     //try{
     CString nstr;
     mysql->holeKonfigurationen();

     mysql->holeArten(pDC,wndFilterKontrolleDialog.ErgebnisFilter);
     //AfxMessageBox("hole Arten",MB_YESNO,0);

     // fügen Konfigurations IDs der ComboBox hinzu
     for(int i=0;i<mysql->konfigurationenAnzahl;i++){
     //char konfString[11];
     //_itoa_s(mysql->konfigurationen[i], konfString , 10);
     //CString str(konfString); 
     nstr.Format(_T("%d"),mysql->konfigurationen[i]);
     

     //wndFilterKontrolleDialog.ComboBox->AddString((LPCTSTR)str);
     wndFilterKontrolleDialog.m_konfigID.AddString(nstr);
     //wndFilterKontrolleDialog.ComboBox->AddString((LPCTSTR)nstr);
     //AfxMessageBox("in Konfigurationen",MB_YESNO,0);
     }

     //AfxMessageBox("nach Konfigurationen",MB_YESNO,0);
     // wählen die erste KonfigurationsID aus
     //char konfStringAuswahl[11];
     //_itoa_s(mysql->konfigurationen[0], konfStringAuswahl , 10);
     //CString str(konfStringAuswahl); 
     nstr.Format(_T("%d"),mysql->konfigurationen[0]);
     wndFilterKontrolleDialog.m_konfigID.SelectString(0,nstr);
     if(wndFilterKontrolleDialog.erneuereCombobox==true){
     for(int i=0;i<mysql->artenAnzahl[wndFilterKontrolleDialog.KonfigurationsIndex2];i++){
     wndFilterKontrolleDialog.addArt((LPCTSTR)mysql->ArtenNamen[wndFilterKontrolleDialog.KonfigurationsIndex2][i]);
     //wndFilterKontrolleDialog.ComboBox2->AddString((LPCTSTR)mysql->ArtenNamen[wndFilterKontrolleDialog.KonfigurationsIndex2][i]);
     wndFilterKontrolleDialog.m_combo2.SelectString(0,(LPCTSTR)mysql->ArtenNamen[wndFilterKontrolleDialog.KonfigurationsIndex2][0]);
     wndFilterKontrolleDialog.erneuereCombobox = false;
     }
     }
     //AfxMessageBox("vor dem Zeichnen",MB_YESNO,0);
     // zeichne alles Pixel ohne Ergebnisse
     if(wndFilterKontrolleDialog.zeigeAllgemein){
     mysql->holePixel(pDC,wndFilterKontrolleDialog.Filter);
     }

     // zeichne den Ergebnis Layer darüber
     if(wndFilterKontrolleDialog.zeigeErgebnisse){
     konfid = wndFilterKontrolleDialog.KonfigurationsIndex2;
     konfigurationsInt = mysql->konfigurationen[konfid];

     if(wndFilterKontrolleDialog.ErgebnisFilter == mysql->ART_FILTER || wndFilterKontrolleDialog.ErgebnisFilter == mysql->QUALITAET_FILTER){
     mysql->holeArtenLayer(pDC,wndFilterKontrolleDialog.ErgebnisFilter,konfigurationsInt,wndFilterKontrolleDialog.KonfigurationsIndex2,wndFilterKontrolleDialog.ArtenIndex);
     }else{
     mysql->holeErgebnisLayer(pDC,wndFilterKontrolleDialog.ErgebnisFilter,konfigurationsInt);
     }
     }	
     mysql->holeUmriss(pDC);
     
     // plottet die Konfigurations ID aus.
     char bufferKonfID[33] ;
     //itoa(konfigurationsInt,bufferKonfID,10);
     //CString str3(bufferKonfID);
     CString str3;
     str3.Format(_T("%d"),konfigurationsInt);

     pDC->SetTextColor(RGB(0, 0, 0));
     pDC->TextOut(10, 30, _T("Konfigurations ID:") );
     pDC->TextOut(10, 30+20, str3 );
     // trennen die Datenbank Verbindung

     // falls der speicher Bool gesetzt ist speichern wir die jetzige Ansicht ab
     /*if(wndFilterKontrolleDialog.speichereBild){
     if(wndFilterKontrolleDialog.ErgebnisFilter == mysql->ART_FILTER || wndFilterKontrolleDialog.ErgebnisFilter == mysql->QUALITAET_FILTER){
     this->speicherBildAb(pDC,konfigurationsInt,wndFilterKontrolleDialog.Filter,mysql->ArtenNamen[wndFilterKontrolleDialog.KonfigurationsIndex2][wndFilterKontrolleDialog.ArtenIndex]);
     }else{
     this->speicherBildAb(pDC,konfigurationsInt,wndFilterKontrolleDialog.Filter,_T("-1"));
     }
     wndFilterKontrolleDialog.speichereBild = false;
     }
     */
    //	mysql->closeConnection();

    /*}catch(sql::SQLException &e) {
     int code =  e.getErrorCode();
     string error = e.what();
     char er[1000];
     lstrcpy(er, error.c_str());
     AfxMessageBox(er,MB_YESNO,0);
     }*/

}

/**
 *
 *
 */
void CEcopayView::speicherBildAb(
        CDC *pDC,
        int konfID,
        int filterID,
        CString artName)
{
    // bauen Dateinamen zusammen:
    char KonfString[ 11];
    _itoa_s( konfID, KonfString, 10);
    CString str( KonfString);
    char filterString[ 11];
    _itoa_s( filterID, filterString, 10);
    CString str2( filterString);
    str.Append( _T( "_"));
    str.Append( str2);
    if( artName != "-1")
    {
        str.Append( _T( "_"));
        str.Append( artName);
    }
    str.Append( _T( ".bmp"));

    WndToBmp( pDC, str);
    ReleaseDC( pDC);
}

/**
 * Speichern das Paint Object als Bitmap ab.
 * Quelle : http://www.codeguru.com/forum/archive/index.php/t-345757.html
 * @param CDC *pDC - Paint Object.
 * @param CString szFile - Dateiname
 */
BOOL CEcopayView::WndToBmp( CDC *pDC, CString szFile)
{
    CString fname = szFile;
    CBitmap bmp, *pOldBmp;
    CRect rect;
    CWnd *pWnd;
    BOOL flg = 0;
    CPalette pal;
    LOGPALETTE *pLp;

    if( pDC == NULL)
    {
        return FALSE;
    }
    pWnd = pDC->GetWindow();

    pWnd->GetClientRect( &rect);

    if( fname.IsEmpty())
        return FALSE;

    CDC memdc;

    memdc.CreateCompatibleDC( pDC);
    bmp.CreateCompatibleBitmap( pDC, rect.Width(), rect.Height());
    pOldBmp = memdc.SelectObject( &bmp);
    memdc.BitBlt( 0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);

    if( pDC->GetDeviceCaps( RASTERCAPS) & RC_PALETTE)
    {
        int nSize;
        nSize = sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * 256;
        pLp = (LOGPALETTE*) new BYTE[ nSize];
        pLp->palVersion = 0x300;
        pLp->palNumEntries = 256;
        GetSystemPaletteEntries( pDC->m_hDC, 0, 256, pLp->palPalEntry);
        pal.CreatePalette( pLp);
        delete[] pLp;
    }

    memdc.SelectObject( pOldBmp);
    HANDLE hDIB = DDBToDIB( bmp, BI_RGB, &pal);
    if( hDIB == NULL)
        return FALSE;

    CFile m_file;
    if( !m_file.Open( fname, CFile::modeWrite | CFile::modeCreate, NULL))
        return FALSE;
    else
        flg = 1;
    BITMAPFILEHEADER hdr;
    LPBITMAPINFOHEADER lpbi;

    lpbi = (LPBITMAPINFOHEADER) hDIB;

    int nColors = 1 << lpbi->biBitCount;

    hdr.bfType = ((WORD)( 'M' << 8) | 'B');
    hdr.bfSize = GlobalSize( hDIB) + sizeof(hdr);
    hdr.bfReserved1 = 0;
    hdr.bfReserved2 = 0;
    hdr.bfOffBits = (DWORD)(
            sizeof(hdr) + lpbi->biSize + nColors * sizeof(RGBQUAD));
    m_file.Write( &hdr, sizeof(hdr));
    m_file.Write( lpbi, GlobalSize( hDIB));
    m_file.Close();

    CBinFile m_tempFile;
    BYTE dummy = 0; //14
    BYTE pBuf[ 14];

    BOOL fres = m_tempFile.Open( fname,
            CFile::modeReadWrite | CFile::typeBinary);

    if( fres == 0)
        return FALSE;

    UINT tt = m_tempFile.Read( pBuf, 14);
    pBuf[ 13] = dummy;
    m_tempFile.SeekToBegin();
    m_tempFile.Write( pBuf, 14);

    m_tempFile.Close();

    return flg;

}
/**
 * Wandelt DDB in DIB um. Dies hilft uns beim schreiben des Bitmaps.
 * Quelle : http://www.codeguru.com/Cpp/G-M/bitmap/article.php/c1765
 * @param CBitmap &bitmap - Bitmap
 * @param DWORD dwCompression - Art der Kompression -> Bitmapheader
 * @param CPalette *pPal - Farb Palette (in Bit)
 */
HANDLE CEcopayView::DDBToDIB(
        CBitmap &bitmap,
        DWORD dwCompression,
        CPalette *pPal)
{

    BITMAP bm;
    BITMAPINFOHEADER bi;
    LPBITMAPINFOHEADER lpbi;
    DWORD dwLen;
    HANDLE hDIB;
    HANDLE handle;
    HDC hDC;
    HPALETTE hPal;

    ASSERT( bitmap.GetSafeHandle());

    // The function has no arg for bitfields
    if( dwCompression == BI_BITFIELDS)
        return NULL;

    // If a palette has not been supplied use defaul palette
    hPal = (HPALETTE) pPal->GetSafeHandle();
    if( hPal == NULL)
        hPal = (HPALETTE) GetStockObject( DEFAULT_PALETTE);

    // Get bitmap information
    bitmap.GetObject( sizeof(bm), (LPSTR) & bm);

    // Initialize the bitmapinfoheader
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bm.bmWidth;
    bi.biHeight = bm.bmHeight;
    bi.biPlanes = 1;
    bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel; //bm.bmPlanes * bm.bmBitsPixel;
    bi.biCompression = dwCompression;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;

    // Compute the size of the  infoheader and the color table
    int nColors = (1 << bi.biBitCount);
    if( nColors > 256)
        nColors = 0;
    dwLen = bi.biSize + nColors * sizeof(RGBQUAD);

    // We need a device context to get the DIB from
    hDC = ::GetDC( NULL);
    hPal = SelectPalette( hDC, hPal, FALSE);
    RealizePalette( hDC);

    // Allocate enough memory to hold bitmapinfoheader and color table
    hDIB = GlobalAlloc( GMEM_FIXED, dwLen);

    if( !hDIB)
    {
        SelectPalette( hDC, hPal, FALSE);
        ::ReleaseDC( NULL, hDC);
        return NULL;
    }

    lpbi = (LPBITMAPINFOHEADER) hDIB;

    *lpbi = bi;

    // Call GetDIBits with a NULL lpBits param, so the device driver 
    // will calculate the biSizeImage field 
    GetDIBits( hDC, (HBITMAP) bitmap.GetSafeHandle(), 0L, (DWORD) bi.biHeight,
            (LPBYTE) NULL, (LPBITMAPINFO) lpbi, (DWORD) DIB_RGB_COLORS);

    bi = *lpbi;

    // If the driver did not fill in the biSizeImage field, then compute it
    // Each scan line of the image is aligned on a DWORD (32bit) boundary
    if( bi.biSizeImage == 0)
    {
        bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
                * bi.biHeight;

        // If a compression scheme is used the result may infact be larger
        // Increase the size to account for this.
        if( dwCompression != BI_RGB)
            bi.biSizeImage = (bi.biSizeImage * 3) / 2;
    }

    // Realloc the buffer so that it can hold all the bits
    dwLen += bi.biSizeImage;
    if( handle = GlobalReAlloc( hDIB, dwLen, GMEM_MOVEABLE))
        hDIB = handle;
    else
    {
        GlobalFree( hDIB);

        // Reselect the original palette
        SelectPalette( hDC, hPal, FALSE);
        ::ReleaseDC( NULL, hDC);
        return NULL;
    }

    // Get the bitmap bits
    lpbi = (LPBITMAPINFOHEADER) hDIB;

    // FINALLY get the DIB
    BOOL bGotBits = GetDIBits( hDC, (HBITMAP) bitmap.GetSafeHandle(), 0L, // Start scan line
            (DWORD) bi.biHeight, // # of scan lines
            (LPBYTE) lpbi // address for bitmap bits
            + (bi.biSize + nColors * sizeof(RGBQUAD)), (LPBITMAPINFO) lpbi, // address of bitmapinfo
            (DWORD) DIB_RGB_COLORS); // Use RGB for color table

    if( !bGotBits)
    {
        GlobalFree( hDIB);

        SelectPalette( hDC, hPal, FALSE);
        ::ReleaseDC( NULL, hDC);
        return NULL;
    }

    SelectPalette( hDC, hPal, FALSE);
    ::ReleaseDC( NULL, hDC);

    return hDIB;

}

// CEcopayView drucken

BOOL CEcopayView::OnPreparePrinting( CPrintInfo* pInfo)
{
    // Standardvorbereitung
    return DoPreparePrinting( pInfo);
}

void CEcopayView::OnBeginPrinting( CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: Zusätzliche Initialisierung vor dem Drucken hier einfügen
}

void CEcopayView::OnEndPrinting( CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: Bereinigung nach dem Drucken einfügen
}

// CEcopayView-Diagnose

#ifdef _DEBUG
void CEcopayView::AssertValid() const
{
    CView::AssertValid();
}

void CEcopayView::Dump(CDumpContext& dc) const
{
    CView::Dump(dc);
}

CEcopayDoc* CEcopayView::GetDocument() const // Nicht-Debugversion ist inline
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CEcopayDoc)));
    return (CEcopayDoc*)m_pDocument;
}
#endif //_DEBUG

// CEcopayView-Meldungshandler

// Anwendungsbefehl zum Ausführen des Dialogfelds

