/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/


#include "precompiled_basctl.hxx"

#include "basicrenderable.hxx"
#include "bastypes.hxx"
#include "basidesh.hrc"

#include "com/sun/star/awt/XDevice.hpp"
#include "toolkit/awt/vclxdevice.hxx"
#include "vcl/print.hxx"
#include "tools/multisel.hxx"
#include "tools/resary.hxx"

using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace basicide;

BasicRenderable::BasicRenderable( IDEBaseWindow* pWin )
: cppu::WeakComponentImplHelper1< com::sun::star::view::XRenderable >( maMutex )
, mpWindow( pWin )
{
    ResStringArray aStrings( IDEResId( RID_PRINTDLG_STRLIST )  );
    DBG_ASSERT( aStrings.Count() >= 3, "resource incomplete" );
    if( aStrings.Count() < 3 ) // bad resource ?
        return;

    m_aUIProperties.realloc( 3 );

    // create Subgroup for print range
    vcl::PrinterOptionsHelper::UIControlOptions aPrintRangeOpt;
    aPrintRangeOpt.maGroupHint = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintRange" ) );
    aPrintRangeOpt.mbInternalOnly = sal_True;
    m_aUIProperties[0].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 0 ) ),
                                                      rtl::OUString(),
                                                      aPrintRangeOpt
                                                      );

    // create a choice for the range to print
    rtl::OUString aPrintContentName( RTL_CONSTASCII_USTRINGPARAM( "PrintContent" ) );
    Sequence< rtl::OUString > aChoices( 2 );
    Sequence< rtl::OUString > aHelpIds( 2 );
    aChoices[0] = aStrings.GetString( 1 );
    aHelpIds[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:0" ) );
    aChoices[1] = aStrings.GetString( 2 );
    aHelpIds[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:1" ) );
    m_aUIProperties[1].Value = getChoiceControlOpt( rtl::OUString(),
                                                    aHelpIds,
                                                    aPrintContentName,
                                                    aChoices,
                                                    0 );

    // create a an Edit dependent on "Pages" selected
    vcl::PrinterOptionsHelper::UIControlOptions aPageRangeOpt( aPrintContentName, 1, sal_True );
    m_aUIProperties[2].Value = getEditControlOpt( rtl::OUString(),
                                                  rtl::OUString(),
                                                  rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ),
                                                  rtl::OUString(),
                                                  aPageRangeOpt
                                                  ); 
}

BasicRenderable::~BasicRenderable()
{
}

Printer* BasicRenderable::getPrinter()
{
    Printer* pPrinter = NULL;
    Any aValue( getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RenderDevice" ) ) ) );
    Reference<awt::XDevice> xRenderDevice;

    if( aValue >>= xRenderDevice )
    {
        VCLXDevice* pDevice = VCLXDevice::GetImplementation(xRenderDevice);
        OutputDevice* pOut = pDevice ? pDevice->GetOutputDevice() : NULL;
        pPrinter = dynamic_cast<Printer*>(pOut);
    }
    return pPrinter;
}

sal_Int32 SAL_CALL BasicRenderable::getRendererCount (
        const Any&, const Sequence<beans::PropertyValue >& i_xOptions
        ) throw (lang::IllegalArgumentException, RuntimeException)
{
    processProperties( i_xOptions );

    sal_Int32 nCount = 0;
    if( mpWindow )
    {
        Printer* pPrinter = getPrinter();
        if( pPrinter )
        {
            nCount = mpWindow->countPages( pPrinter );
            sal_Int64 nContent = getIntValue( "PrintContent", -1 );
            if( nContent == 1 )
            {
                rtl::OUString aPageRange( getStringValue( "PageRange" ) );
                MultiSelection aSel( aPageRange );
                long nSelCount = aSel.GetSelectCount();
                if( nSelCount >= 0 && nSelCount < nCount )
                    nCount = nSelCount;
            }
        }
        else
            throw lang::IllegalArgumentException();
    }
    
    return nCount;
}
    
Sequence<beans::PropertyValue> SAL_CALL BasicRenderable::getRenderer (
        sal_Int32, const Any&, const Sequence<beans::PropertyValue>& i_xOptions
        ) throw (lang::IllegalArgumentException, RuntimeException)
{
    processProperties( i_xOptions );

    Sequence< beans::PropertyValue > aVals;
    // insert page size here
    Printer* pPrinter = getPrinter();
    // no renderdevice is legal; the first call is to get our print ui options
    if( pPrinter )
    {
        Size aPageSize( pPrinter->PixelToLogic( pPrinter->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) );
        
        aVals.realloc( 1 );
        aVals[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) );
        awt::Size aSize;
        aSize.Width  = aPageSize.Width();
        aSize.Height = aPageSize.Height();
        aVals[0].Value <<= aSize;
    }
        
    appendPrintUIOptions( aVals );

    return aVals;
}
    
void SAL_CALL BasicRenderable::render (
        sal_Int32 nRenderer, const Any&,
        const Sequence<beans::PropertyValue>& i_xOptions
        ) throw (lang::IllegalArgumentException, RuntimeException)
{
    processProperties( i_xOptions );

    if( mpWindow )
    {
        Printer* pPrinter = getPrinter();
        if( pPrinter )
        {
            sal_Int64 nContent = getIntValue( "PrintContent", -1 );
            if( nContent == 1 )
            {
                rtl::OUString aPageRange( getStringValue( "PageRange" ) );
                MultiSelection aSel( aPageRange );
                long nSelect = aSel.FirstSelected();
                while( nSelect != long(SFX_ENDOFSELECTION) && nRenderer-- )
                    nSelect = aSel.NextSelected();
                if( nSelect != long(SFX_ENDOFSELECTION) )
                    mpWindow->printPage( sal_Int32(nSelect-1), pPrinter );
            }
            else
                mpWindow->printPage( nRenderer, pPrinter );
        }
        else
            throw lang::IllegalArgumentException();
    }
}


