/**************************************************************
 *
 * 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.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_forms.hxx"
#include "rtattributehandler.hxx"

#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#include <editeng/eeitem.hxx>
#include <svl/itemset.hxx>
#include <svl/itempool.hxx>
#include <tools/mapunit.hxx>
#include <vcl/mapmod.hxx>
#include <vcl/outdev.hxx>

#define ITEMID_ADJUST       EE_PARA_JUST
#include <editeng/adjitem.hxx>
#define ITEMID_WEIGHT       EE_CHAR_WEIGHT
#include <editeng/wghtitem.hxx>
#define ITEMID_ESCAPEMENT   EE_CHAR_ESCAPEMENT
#include <editeng/escpitem.hxx>
#define ITEMID_LINESPACING  EE_PARA_SBL
#include <editeng/lspcitem.hxx>
#define ITEMID_FONTHEIGHT   EE_CHAR_FONTHEIGHT
#include <editeng/fhgtitem.hxx>
#define ITEMID_FRAMEDIR     EE_PARA_WRITINGDIR
#include <editeng/frmdiritem.hxx>
#include <editeng/scripttypeitem.hxx>

//........................................................................
namespace frm
{
//........................................................................
    //====================================================================
	//= ReferenceBase
	//====================================================================
	//--------------------------------------------------------------------
    oslInterlockedCount SAL_CALL ReferenceBase::acquire()
    {
        return osl_incrementInterlockedCount( &m_refCount );
    }

	//--------------------------------------------------------------------
	oslInterlockedCount SAL_CALL ReferenceBase::release()
    {
        return osl_decrementInterlockedCount( &m_refCount );
    }

	//--------------------------------------------------------------------
    ReferenceBase::~ReferenceBase()
    {
    }

    //====================================================================
	//= AttributeHandler
	//====================================================================
	//--------------------------------------------------------------------
    AttributeHandler::AttributeHandler( AttributeId _nAttributeId, WhichId _nWhichId )
        :m_nAttribute( _nAttributeId )
        ,m_nWhich    ( _nWhichId     )
    {
    }

	//--------------------------------------------------------------------
    AttributeHandler::~AttributeHandler()
    {
    }

	//--------------------------------------------------------------------
	oslInterlockedCount SAL_CALL AttributeHandler::acquire()
    {
        return ReferenceBase::acquire();
    }

	//--------------------------------------------------------------------
	oslInterlockedCount SAL_CALL AttributeHandler::release()
    {
        return ReferenceBase::release();
    }

	//--------------------------------------------------------------------
    AttributeId AttributeHandler::getAttributeId( ) const
    {
        return getAttribute();
    }

	//--------------------------------------------------------------------
    AttributeCheckState AttributeHandler::implGetCheckState( const SfxPoolItem& /*_rItem*/ ) const
    {
        OSL_ENSURE( sal_False, "AttributeHandler::implGetCheckState: not to be called!" );
        return eIndetermined;
    }

	//--------------------------------------------------------------------
    void AttributeHandler::putItemForScript( SfxItemSet& _rAttribs, const SfxPoolItem& _rItem, ScriptType _nForScriptType ) const
    {
        SvxScriptSetItem aSetItem( (WhichId)getAttributeId(), *_rAttribs.GetPool() );
        aSetItem.PutItemForScriptType( _nForScriptType, _rItem );
        _rAttribs.Put( aSetItem.GetItemSet(), sal_False );
    }

	//--------------------------------------------------------------------
    AttributeCheckState AttributeHandler::getCheckState( const SfxItemSet& _rAttribs ) const
    {
        AttributeCheckState eSimpleState( eIndetermined );
        const SfxPoolItem* pItem = _rAttribs.GetItem( getWhich() );
        if ( pItem )
            eSimpleState = implGetCheckState( *pItem );
        return eSimpleState;
    }

	//--------------------------------------------------------------------
    AttributeState AttributeHandler::getState( const SfxItemSet& _rAttribs ) const
    {
        AttributeState aState( eIndetermined );
        aState.eSimpleState = getCheckState( _rAttribs );
        return aState;
    }

    //====================================================================
	//= AttributeHandlerFactory
	//====================================================================
	//--------------------------------------------------------------------
    namespace
    {
        static WhichId lcl_implGetWhich( const SfxItemPool& _rPool, AttributeId _nAttributeId )
        {
            WhichId nWhich = 0;
            switch ( _nAttributeId )
            {
            case SID_ATTR_CHAR_LATIN_FONTHEIGHT:nWhich = EE_CHAR_FONTHEIGHT;break;
            case SID_ATTR_CHAR_LATIN_FONT:      nWhich = EE_CHAR_FONTINFO;  break;
            case SID_ATTR_CHAR_LATIN_LANGUAGE:  nWhich = EE_CHAR_LANGUAGE;  break;
            case SID_ATTR_CHAR_LATIN_POSTURE:   nWhich = EE_CHAR_ITALIC;    break;
            case SID_ATTR_CHAR_LATIN_WEIGHT:    nWhich = EE_CHAR_WEIGHT;    break;

            default:
                nWhich = _rPool.GetWhich( (SfxSlotId)_nAttributeId );
            }
            return nWhich;
        }
    }
	//--------------------------------------------------------------------
    ::rtl::Reference< IAttributeHandler > AttributeHandlerFactory::getHandlerFor( AttributeId _nAttributeId, const SfxItemPool& _rEditEnginePool )
    {
        ::rtl::Reference< IAttributeHandler > pReturn;
        switch ( _nAttributeId )
        {
        case SID_ATTR_PARA_ADJUST_LEFT  :
		case SID_ATTR_PARA_ADJUST_CENTER:
		case SID_ATTR_PARA_ADJUST_RIGHT :
		case SID_ATTR_PARA_ADJUST_BLOCK :
            pReturn = new ParaAlignmentHandler( _nAttributeId );
            break;

        case SID_ATTR_PARA_LINESPACE_10:
	    case SID_ATTR_PARA_LINESPACE_15:
		case SID_ATTR_PARA_LINESPACE_20:
            pReturn = new LineSpacingHandler( _nAttributeId );
            break;

        case SID_SET_SUPER_SCRIPT:
        case SID_SET_SUB_SCRIPT:
            pReturn = new EscapementHandler( _nAttributeId );
            break;

        case SID_ATTR_CHAR_FONTHEIGHT:
        case SID_ATTR_CHAR_CTL_FONTHEIGHT:
        case SID_ATTR_CHAR_CJK_FONTHEIGHT:
        case SID_ATTR_CHAR_LATIN_FONTHEIGHT:
            pReturn = new FontSizeHandler( _nAttributeId, lcl_implGetWhich( _rEditEnginePool, _nAttributeId ) );
            break;

        case SID_ATTR_PARA_LEFT_TO_RIGHT:
        case SID_ATTR_PARA_RIGHT_TO_LEFT:
            pReturn = new ParagraphDirectionHandler( _nAttributeId );
            break;

        case SID_ATTR_PARA_HANGPUNCTUATION:
        case SID_ATTR_PARA_FORBIDDEN_RULES:
        case SID_ATTR_PARA_SCRIPTSPACE:
            pReturn = new BooleanHandler( _nAttributeId, lcl_implGetWhich( _rEditEnginePool, _nAttributeId ) );
            break;

        default:
            pReturn = new SlotHandler( (SfxSlotId)_nAttributeId, lcl_implGetWhich( _rEditEnginePool, _nAttributeId ) );
            break;

        }

        return pReturn;
    }

    //====================================================================
	//= ParaAlignmentHandler
	//====================================================================
	//--------------------------------------------------------------------
    ParaAlignmentHandler::ParaAlignmentHandler( AttributeId _nAttributeId )
        :AttributeHandler( _nAttributeId, EE_PARA_JUST )
        ,m_eAdjust( SVX_ADJUST_CENTER )
    {
        switch ( getAttribute() )
        {
            case SID_ATTR_PARA_ADJUST_LEFT  : m_eAdjust = SVX_ADJUST_LEFT;    break;
	    	case SID_ATTR_PARA_ADJUST_CENTER: m_eAdjust = SVX_ADJUST_CENTER;  break;
		    case SID_ATTR_PARA_ADJUST_RIGHT : m_eAdjust = SVX_ADJUST_RIGHT;   break;
		    case SID_ATTR_PARA_ADJUST_BLOCK : m_eAdjust = SVX_ADJUST_BLOCK;   break;
            default:
                OSL_ENSURE( sal_False, "ParaAlignmentHandler::ParaAlignmentHandler: invalid slot!" );
                break;
        }
    }

	//--------------------------------------------------------------------
    AttributeCheckState ParaAlignmentHandler::implGetCheckState( const SfxPoolItem& _rItem ) const
    {
        OSL_ENSURE( _rItem.ISA( SvxAdjustItem ), "ParaAlignmentHandler::implGetCheckState: invalid pool item!" );
        SvxAdjust eAdjust = static_cast< const SvxAdjustItem& >( _rItem ).GetAdjust();
        return ( eAdjust == m_eAdjust ) ? eChecked : eUnchecked;
    }

	//--------------------------------------------------------------------
    void ParaAlignmentHandler::executeAttribute( const SfxItemSet& /*_rCurrentAttribs*/, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType /*_nForScriptType*/ ) const
    {
        OSL_ENSURE( !_pAdditionalArg, "ParaAlignmentHandler::executeAttribute: this is a simple toggle attribute - no args possible!" );
        (void)_pAdditionalArg;
        _rNewAttribs.Put( SvxAdjustItem( m_eAdjust, getWhich() ) );
    }

    //====================================================================
	//= LineSpacingHandler
	//====================================================================
	//--------------------------------------------------------------------
    LineSpacingHandler::LineSpacingHandler( AttributeId _nAttributeId )
        :AttributeHandler( _nAttributeId, EE_PARA_SBL )
        ,m_nLineSpace( 100 )
    {
        switch ( getAttribute() )
        {
            case SID_ATTR_PARA_LINESPACE_10: m_nLineSpace = 100; break;
	    	case SID_ATTR_PARA_LINESPACE_15: m_nLineSpace = 150; break;
		    case SID_ATTR_PARA_LINESPACE_20: m_nLineSpace = 200; break;
            default:
                OSL_ENSURE( sal_False, "LineSpacingHandler::LineSpacingHandler: invalid slot!" );
                break;
        }
    }

	//--------------------------------------------------------------------
    AttributeCheckState LineSpacingHandler::implGetCheckState( const SfxPoolItem& _rItem ) const
    {
        OSL_ENSURE( _rItem.ISA( SvxLineSpacingItem ), "LineSpacingHandler::implGetCheckState: invalid pool item!" );
        sal_uInt16 nLineSpace = static_cast< const SvxLineSpacingItem& >( _rItem ).GetPropLineSpace();
        return ( nLineSpace == m_nLineSpace ) ? eChecked : eUnchecked;
    }

	//--------------------------------------------------------------------
    void LineSpacingHandler::executeAttribute( const SfxItemSet& /*_rCurrentAttribs*/, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType /*_nForScriptType*/ ) const
    {
        OSL_ENSURE( !_pAdditionalArg, "LineSpacingHandler::executeAttribute: this is a simple toggle attribute - no args possible!" );
        (void)_pAdditionalArg;

        SvxLineSpacingItem aLineSpacing( m_nLineSpace, getWhich() );
        aLineSpacing.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
        if ( 100 == m_nLineSpace )
            aLineSpacing.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF;
        else
            aLineSpacing.SetPropLineSpace( (sal_uInt8)m_nLineSpace );

        _rNewAttribs.Put( aLineSpacing );
    }

    //====================================================================
	//= EscapementHandler
	//====================================================================
	//--------------------------------------------------------------------
    EscapementHandler::EscapementHandler( AttributeId _nAttributeId )
        :AttributeHandler( _nAttributeId, EE_CHAR_ESCAPEMENT )
        ,m_eEscapement( SVX_ESCAPEMENT_OFF )
    {
        switch ( getAttribute() )
        {
            case SID_SET_SUPER_SCRIPT   : m_eEscapement = SVX_ESCAPEMENT_SUPERSCRIPT; break;
	    	case SID_SET_SUB_SCRIPT     : m_eEscapement = SVX_ESCAPEMENT_SUBSCRIPT;   break;
            default:
                OSL_ENSURE( sal_False, "EscapementHandler::EscapementHandler: invalid slot!" );
                break;
        }
    }

	//--------------------------------------------------------------------
    AttributeCheckState EscapementHandler::implGetCheckState( const SfxPoolItem& _rItem ) const
    {
        OSL_ENSURE( _rItem.ISA( SvxEscapementItem ), "EscapementHandler::getState: invalid pool item!" );
        SvxEscapement eEscapement = static_cast< const SvxEscapementItem& >( _rItem ).GetEscapement();
        return ( eEscapement == m_eEscapement ) ? eChecked : eUnchecked;
    }

	//--------------------------------------------------------------------
    void EscapementHandler::executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType /*_nForScriptType*/ ) const
    {
        OSL_ENSURE( !_pAdditionalArg, "EscapementHandler::executeAttribute: this is a simple toggle attribute - no args possible!" );
            // well, in theory we could allow an SvxEscapementItem here, but this is not needed
        (void)_pAdditionalArg;

        bool bIsChecked = getCheckState( _rCurrentAttribs ) == eChecked;
        _rNewAttribs.Put( SvxEscapementItem( bIsChecked ? SVX_ESCAPEMENT_OFF : m_eEscapement, getWhich() ) );
    }

    //====================================================================
	//= SlotHandler
	//====================================================================
    //--------------------------------------------------------------------
    SlotHandler::SlotHandler( AttributeId _nAttributeId, WhichId _nWhichId )
        :AttributeHandler( _nAttributeId, _nWhichId )
        ,m_bScriptDependent( false )
    {
        m_bScriptDependent = ( SID_ATTR_CHAR_WEIGHT == _nAttributeId )
                         ||  ( SID_ATTR_CHAR_POSTURE == _nAttributeId )
                         ||  ( SID_ATTR_CHAR_FONT == _nAttributeId );
    }

    //--------------------------------------------------------------------
    AttributeState SlotHandler::getState( const SfxItemSet& _rAttribs ) const
    {
        AttributeState aState( eIndetermined );

        const SfxPoolItem* pItem = _rAttribs.GetItem( getWhich() );
        if ( pItem )
            aState.setItem( pItem->Clone() );

        return aState;
    }

    //--------------------------------------------------------------------
    void SlotHandler::executeAttribute( const SfxItemSet& /*_rCurrentAttribs*/, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType _nForScriptType ) const
    {
        if ( _pAdditionalArg )
        {
            SfxPoolItem* pCorrectWich = _pAdditionalArg->Clone();
            pCorrectWich->SetWhich( getWhich() );

            if ( m_bScriptDependent )
                putItemForScript( _rNewAttribs, *pCorrectWich, _nForScriptType );
            else
                _rNewAttribs.Put( *pCorrectWich );
            DELETEZ( pCorrectWich );
        }
        else
            OSL_ENSURE( sal_False, "SlotHandler::executeAttribute: need attributes to do something!" );
    }

    //====================================================================
	//= FontSizeHandler
	//====================================================================
    //--------------------------------------------------------------------
    FontSizeHandler::FontSizeHandler( AttributeId _nAttributeId, WhichId _nWhichId )
        :AttributeHandler( _nAttributeId, _nWhichId )
    {
        OSL_ENSURE( ( _nAttributeId == SID_ATTR_CHAR_FONTHEIGHT ) || ( _nAttributeId == SID_ATTR_CHAR_CTL_FONTHEIGHT )
            || ( _nAttributeId == SID_ATTR_CHAR_CJK_FONTHEIGHT ) || ( _nAttributeId == SID_ATTR_CHAR_LATIN_FONTHEIGHT ),
            "FontSizeHandler::FontSizeHandler: invalid attribute id!" );
    }

    //--------------------------------------------------------------------
    AttributeState FontSizeHandler::getState( const SfxItemSet& _rAttribs ) const
    {
        AttributeState aState( eIndetermined );

        const SfxPoolItem* pItem = _rAttribs.GetItem( getWhich() );
        const SvxFontHeightItem* pFontHeightItem = PTR_CAST( SvxFontHeightItem, pItem );
        OSL_ENSURE( pFontHeightItem || !pItem, "FontSizeHandler::getState: invalid item!" );
        if ( pFontHeightItem )
        {
            // by definition, the item should have the unit twip
            sal_uLong nHeight = pFontHeightItem->GetHeight();
            if ( _rAttribs.GetPool()->GetMetric( getWhich() ) != SFX_MAPUNIT_TWIP )
            {
                nHeight = OutputDevice::LogicToLogic(
                    Size( 0, nHeight ),
                    MapMode( (MapUnit)( _rAttribs.GetPool()->GetMetric( getWhich() ) ) ),
                    MapMode( MAP_TWIP )
                ).Height();
            }

            SvxFontHeightItem* pNewItem = new SvxFontHeightItem( nHeight, 100, getWhich() );
            pNewItem->SetProp( pFontHeightItem->GetProp(), pFontHeightItem->GetPropUnit() );
            aState.setItem( pNewItem );
        }

        return aState;
    }

    //--------------------------------------------------------------------
    void FontSizeHandler::executeAttribute( const SfxItemSet& /*_rCurrentAttribs*/, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType _nForScriptType ) const
    {
        const SvxFontHeightItem* pFontHeightItem = PTR_CAST( SvxFontHeightItem, _pAdditionalArg );
        OSL_ENSURE( pFontHeightItem, "FontSizeHandler::executeAttribute: need a FontHeightItem!" );

        if ( pFontHeightItem )
        {
            // correct measurement units
            SfxMapUnit eItemMapUnit = pFontHeightItem->GetPropUnit(); (void)eItemMapUnit;
            sal_uLong nHeight = pFontHeightItem->GetHeight();
            if ( _rNewAttribs.GetPool()->GetMetric( getWhich() ) != SFX_MAPUNIT_TWIP )
            {
                nHeight = OutputDevice::LogicToLogic(
                    Size( 0, nHeight ),
                    MapMode( (MapUnit)( SFX_MAPUNIT_TWIP ) ),
                    MapMode( (MapUnit)( _rNewAttribs.GetPool()->GetMetric( getWhich() ) ) )
                ).Height();
            }

            SvxFontHeightItem aNewItem( nHeight, 100, getWhich() );
            aNewItem.SetProp( pFontHeightItem->GetProp(), pFontHeightItem->GetPropUnit() );

            if ( ( getAttributeId() == SID_ATTR_CHAR_FONTHEIGHT ) && _nForScriptType )
                putItemForScript( _rNewAttribs, aNewItem, _nForScriptType );
            else
                _rNewAttribs.Put( aNewItem );
        }
    }

    //====================================================================
	//= ParagraphDirectionHandler
	//====================================================================
    //--------------------------------------------------------------------
    ParagraphDirectionHandler::ParagraphDirectionHandler( AttributeId _nAttributeId )
        :AttributeHandler( _nAttributeId, EE_PARA_WRITINGDIR )
        ,m_eParagraphDirection( FRMDIR_HORI_LEFT_TOP )
        ,m_eDefaultAdjustment( SVX_ADJUST_RIGHT )
        ,m_eOppositeDefaultAdjustment( SVX_ADJUST_LEFT )
    {
        switch ( getAttributeId() )
        {
            case SID_ATTR_PARA_LEFT_TO_RIGHT: m_eParagraphDirection = FRMDIR_HORI_LEFT_TOP; m_eDefaultAdjustment = SVX_ADJUST_LEFT; break;
            case SID_ATTR_PARA_RIGHT_TO_LEFT: m_eParagraphDirection = FRMDIR_HORI_RIGHT_TOP; m_eDefaultAdjustment = SVX_ADJUST_RIGHT; break;
            default:
                OSL_ENSURE( sal_False, "ParagraphDirectionHandler::ParagraphDirectionHandler: invalid attribute id!" );
        }

        if ( SVX_ADJUST_RIGHT == m_eDefaultAdjustment )
            m_eOppositeDefaultAdjustment = SVX_ADJUST_LEFT;
        else
            m_eOppositeDefaultAdjustment = SVX_ADJUST_RIGHT;
    }

	//--------------------------------------------------------------------
    AttributeCheckState ParagraphDirectionHandler::implGetCheckState( const SfxPoolItem& _rItem ) const
    {
        OSL_ENSURE( _rItem.ISA( SvxFrameDirectionItem ), "ParagraphDirectionHandler::implGetCheckState: invalid pool item!" );
        SvxFrameDirection eDirection = static_cast< SvxFrameDirection >( static_cast< const SvxFrameDirectionItem& >( _rItem ).GetValue() );
        return ( eDirection == m_eParagraphDirection ) ? eChecked : eUnchecked;
    }

    //--------------------------------------------------------------------
    void ParagraphDirectionHandler::executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rNewAttribs, const SfxPoolItem* /*_pAdditionalArg*/, ScriptType /*_nForScriptType*/ ) const
    {
        _rNewAttribs.Put( SvxFrameDirectionItem( m_eParagraphDirection, getWhich() ) );

        // if the current adjustment of the was the default adjustment for the *previous* text direction,
        // then we toggle the adjustment, too
        SvxAdjust eCurrentAdjustment = SVX_ADJUST_LEFT;
        const SfxPoolItem* pCurrentAdjustment = NULL;
        if ( SFX_ITEM_ON == _rCurrentAttribs.GetItemState( EE_PARA_JUST, sal_True, &pCurrentAdjustment ) )
            eCurrentAdjustment = static_cast< const SvxAdjustItem* >( pCurrentAdjustment )->GetAdjust();

        if ( eCurrentAdjustment == m_eOppositeDefaultAdjustment )
            _rNewAttribs.Put( SvxAdjustItem( m_eDefaultAdjustment, EE_PARA_JUST ) );
    }

    //====================================================================
	//= BooleanHandler
	//====================================================================
    //--------------------------------------------------------------------
    BooleanHandler::BooleanHandler( AttributeId _nAttributeId, WhichId _nWhichId )
        :AttributeHandler( _nAttributeId, _nWhichId )
    {
    }

    //--------------------------------------------------------------------
    AttributeCheckState BooleanHandler::implGetCheckState( const SfxPoolItem& _rItem ) const
    {
        OSL_ENSURE( _rItem.ISA( SfxBoolItem ), "BooleanHandler::implGetCheckState: invalid item!" );
        if ( _rItem.ISA( SfxBoolItem ) )
            return static_cast< const SfxBoolItem& >( _rItem ).GetValue() ? eChecked : eUnchecked;

        return eIndetermined;
    }

    //--------------------------------------------------------------------
    void BooleanHandler::executeAttribute( const SfxItemSet& /*_rCurrentAttribs*/, SfxItemSet& _rNewAttribs, const SfxPoolItem* _pAdditionalArg, ScriptType /*_nForScriptType*/ ) const
    {
        OSL_ENSURE( _pAdditionalArg && _pAdditionalArg->ISA( SfxBoolItem ), "BooleanHandler::executeAttribute: invalid argument!" );
        if ( _pAdditionalArg )
        {
            SfxPoolItem* pCorrectWich = _pAdditionalArg->Clone();
            pCorrectWich->SetWhich( getWhich() );
            _rNewAttribs.Put( *pCorrectWich );
            DELETEZ( pCorrectWich );
        }
    }

//........................................................................
}   // namespace frm
//........................................................................
