/*
 * ************************************************************************************************************
 * Author: Marcin Załęczny
 * Copyright (C)2011 Marcin Załęczny <mzaleczny@hotmail.com>
 * License: The GNU Lesser General Public License, version 3.0 (LGPLv3)
 * Library Name: mzstdprint
 * Version: 1.02
 * First release date:   2011-02-03
 * Current release date: 2011-03-04
 *
 *
 * This file is part of mzstdprint library
 * 
 * mzstdprint 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 3 of the License, or
 * (at your option) any later version.
 * 
 * mzstdprint library 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 program. If not, see <http://www.gnu.org/licenses/>.
 * ************************************************************************************************************
 */

#ifndef __MZSTDPRINT_PRINTER_H__
#define __MZSTDPRINT_PRINTER_H__

#include "mzstdprintCommon.h"
#include "mzObject.h"
#include "mzString.h"
#include "mzStringList.h"
#include "mzObjectList.h"
#include <winspool.h>
#include "mzPrintTask.h"
#include "mzObjectList.h"

class CPrinterDriverInfo;
class CPrinterInfo;
class CCanvas;

class DECLSPEC_MZSTDPRINT CPrinter : public CObject {
public:
    CCanvas*    canvas;
    // printersArray: Array of created CPrinter objects. Commonly should contain only one value as only
    // one CPrinter object at a time is recommended to create. It is for use by static AbortProc function
    // as the function takes only HDC input param and there is no way to associate custom value with HDC
    // variable.
    static CObjectList* printers;
    
	WINAPI CPrinter(WCHAR* printerName = NULL);
    virtual WINAPI ~CPrinter();

    inline CString WINAPI getName() { return this->_name; }
    // return list of CPrinterInfo* pointers
    static CObjectList* WINAPI getInstalledLocalPrinters(BOOL details1 = TRUE, BOOL details2 = FALSE, BOOL details4 = FALSE, BOOL details5 = FALSE);
    BOOL WINAPI isPrinterInstalled(WCHAR* name);
    BOOL WINAPI open();
    BOOL WINAPI close();
    inline PDEVMODE WINAPI getDevmode() { return (PDEVMODE)this->_devmode; }
    inline CPrinterInfo* WINAPI getPrinterInfo() { return this->_printerInfo; }
    BOOL WINAPI getDriverInfo(CPrinterDriverInfo* pdi);
    BOOL WINAPI showPrinterPropertiesDialogBox(HWND hwnd, BOOL applyDevMode = TRUE, LONG* clickedButton = NULL);
    BOOL WINAPI showCompactedPrinterPropertiesDialogBox(HWND hwnd);
    BOOL WINAPI showPrintDialogBox(HWND hwnd);

    CString WINAPI getPortName();
    CStringList* WINAPI getPaperBins();
    CStringList* WINAPI getPaperSources();
    BOOL WINAPI setDefaultDevmode();
    HDC WINAPI getDC();
    VOID WINAPI deleteDC();
    BOOL WINAPI isPrintingStarted() { return (this->_hdc != NULL) || (this->canvas != NULL); }

    SIZE WINAPI getPixelsPerInch();
    // returns page size in pixels by default,
    //   if unit == L"in", then return size in inches
    //   if unit == L"mm", then return size in milimeters
    //   if unit == L"cm", then return size in centymeters
    SIZE WINAPI getPageSize(WCHAR* unit = NULL);
    
    CString WINAPI getOrientation();
    VOID WINAPI setOrientation(SHORT value);
    CString WINAPI getPaperSize();
    VOID WINAPI setPaperSize(SHORT value);
    VOID WINAPI setPaperSize(WCHAR* value);
    LONG WINAPI getPaperLength();
    VOID WINAPI setPaperLength(SHORT value);
    LONG WINAPI getPaperWidth();
    VOID WINAPI setPaperWidth(SHORT value);
    LONG WINAPI getScale();
    VOID WINAPI setScale(SHORT value);
    LONG WINAPI getCopies();
    VOID WINAPI setCopies(SHORT value);
    CString WINAPI getDefaultSource();
    VOID WINAPI setDefaultSource(SHORT value);
    CString WINAPI getPrintQuality();
    VOID WINAPI setPrintQuality(SHORT value);
    
    VOID WINAPI showInformation();
    BOOL WINAPI print(CPrintTask* printTask);
    BOOL WINAPI printFile(CString fname, WCHAR* documentName = L"Document");
    BOOL WINAPI canPrintBitmaps();
    inline CPrintTask* WINAPI getPrintTask() { return this->_printTask; }

    static BOOL CALLBACK AbortProc(HDC hdc, int nCode);
protected:
    // Printer Name
    CString         _name;
    // Printer Handle
    HANDLE          _hPrinter;
    // Printer Properties (in DEVMODE structure) as its size is system dependent we define it as BYTE*
    BYTE*           _devmode;
    DWORD           _devmodeSize;
    // if devmode was altered and need to be apply to printer settings
    BOOL            _devmodeApplyChanges;
    HDC             _hdc;
    LONG            _printJobId;
    DOCINFO*        _docInfo;
    DOC_INFO_1*     _docInfo1;
    CPrinterInfo*   _printerInfo;
    CPrintTask*     _printTask;

    VOID WINAPI _commonInit(WCHAR* printerName);
    CString WINAPI _paperSourceWordToString(WORD papersource);
    VOID WINAPI _deleteDocInfo();
    VOID WINAPI _deleteDocInfo1();
    DOCINFO* WINAPI _createDocInfo(WCHAR* docName, WCHAR* dataType);
    DOC_INFO_1* WINAPI _createDocInfo1(WCHAR* docName, WCHAR* dataType);
    static CObjectList* WINAPI _enumPrinters(DWORD flags, WCHAR* name, DWORD detailsLevel, CObjectList* listForUpdate = NULL);
    VOID WINAPI _getPrinterInfo(BOOL details1, BOOL details2, BOOL details4, BOOL details5);
    VOID WINAPI _getPrinterInfo(DWORD detailsLevel = 2);
    BOOL WINAPI _beginPrint(WCHAR* documentName = L"Document");
    BOOL WINAPI _beginRawPrint(WCHAR* documentName = L"Document");
    BOOL WINAPI _endPrint();
    BOOL WINAPI _endRawPrint();
    VOID WINAPI _cleanupDevmode();
};
typedef CPrinter* PPrinter;

#endif
