/**************************************************************
 * 
 * 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 <precomp.h>
#include "hd_chlst.hxx"


// NOT FULLY DEFINED SERVICES
#include <ary/ceslot.hxx>
#include <ary/cpp/c_gate.hxx>
#include <ary/cpp/c_namesp.hxx>
#include <ary/cpp/c_class.hxx>
#include <ary/cpp/c_enum.hxx>
#include <ary/cpp/c_tydef.hxx>
#include <ary/cpp/c_funct.hxx>
#include <ary/cpp/c_vari.hxx>
#include <ary/cpp/c_enuval.hxx>
#include <ary/loc/loc_file.hxx>
#include <ary/loc/locp_le.hxx>
#include <ary/doc/d_oldcppdocu.hxx>
#include <ary/info/ci_attag.hxx>
#include <ary/info/ci_text.hxx>
#include <ary/info/all_dts.hxx>
#include "hd_docu.hxx"
#include "opageenv.hxx"
#include "protarea.hxx"
#include "strconst.hxx"


using namespace csi;
using html::Table;
using html::TableRow;
using html::TableCell;
using html::Font;
using html::SizeAttr;
using html::BgColorAttr;
using html::WidthAttr;


const int   ixPublic = 0;
const int   ixProtected = 1;
const int   ixPrivate = 2;

struct ChildList_Display::S_AreaCo
{
  public:
    ProtectionArea      aArea;
    Area_Result *       pResult;

                        S_AreaCo(
                            Area_Result &       o_rResult,
                            const char *        i_sLabel,
                            const char *        i_sTitle );
                        ~S_AreaCo();

    void                PerformResult();

  private:
    csi::xml::Element & Out()                   { return pResult->rOut; }
};


const ary::info::DocuText &
ShortDocu( const ary::cpp::CodeEntity & i_rCe )
{
    static const ary::info::DocuText
        aNull_;

    const ary::doc::OldCppDocu *
            pInfo = dynamic_cast< const ary::doc::OldCppDocu* >( i_rCe.Docu().Data() );
    if (pInfo == 0)
        return aNull_;

    return pInfo->Short().CText();
}


ChildList_Display::ChildList_Display( OuputPage_Environment & io_rEnv )
    :   HtmlDisplay_Impl( io_rEnv ),
        pShortDocu_Display( new Docu_Display(io_rEnv) ),
        pActiveParentClass(0),
        pActiveParentEnum(0),
        // pSglArea,
        // aMemberAreas,
        peClassesFilter(0)
{
}

ChildList_Display::ChildList_Display( OuputPage_Environment & io_rEnv,
                                      const ary::cpp::Class & i_rClass )
    :   HtmlDisplay_Impl( io_rEnv ),
        pShortDocu_Display( new Docu_Display(io_rEnv) ),
        pActiveParentClass(&i_rClass),
        pActiveParentEnum(0),
        // pSglArea,
        // aMemberAreas,
        peClassesFilter(0)
{
}

ChildList_Display::ChildList_Display( OuputPage_Environment & io_rEnv,
                                      const ary::cpp::Enum &  i_rEnum )
    :   HtmlDisplay_Impl( io_rEnv ),
        pShortDocu_Display( new Docu_Display(io_rEnv) ),
        pActiveParentClass(0),
        pActiveParentEnum(&i_rEnum),
        // pSglArea,
        // aMemberAreas,
        peClassesFilter(0)
{
}

ChildList_Display::~ChildList_Display()
{
}

void
ChildList_Display::Run_Simple( Area_Result &       o_rResult,
                               ary::SlotAccessId   i_nSlot,
                               const char *        i_sListLabel,
                               const char *        i_sListTitle )
{
	ary::Slot_AutoPtr
            pSlot( ActiveParent().Create_Slot( i_nSlot ) );
    if ( pSlot->Size() == 0 )
        return;

    pSglArea = new S_AreaCo( o_rResult,
                             i_sListLabel,
                             i_sListTitle );

    pSlot->StoreAt(*this);

    pSglArea->PerformResult();
    pSglArea = 0;
}

void
ChildList_Display::Run_GlobalClasses( Area_Result &        o_rResult,
                                      ary::SlotAccessId    i_nSlot,
                                      const char *         i_sListLabel,
                                      const char *         i_sListTitle,
                                      ary::cpp::E_ClassKey i_eFilter )
{
	ary::Slot_AutoPtr
            pSlot( ActiveParent().Create_Slot( i_nSlot ) );
    if ( pSlot->Size() == 0 )
        return;

    pSglArea = new S_AreaCo( o_rResult,
                             i_sListLabel,
                             i_sListTitle );

    SetClassesFilter(i_eFilter);
    pSlot->StoreAt(*this);
    UnsetClassesFilter();

    pSglArea->PerformResult();
    pSglArea = 0;
}

void
ChildList_Display::Run_Members( Area_Result &           o_rResult_public,
                                Area_Result &           o_rResult_protected,
                                Area_Result &           o_rResult_private,
                                ary::SlotAccessId       i_nSlot,
                                const char *            i_sListLabel_public,
                                const char *            i_sListLabel_protected,
                                const char *            i_sListLabel_private,
                                const char *            i_sListTitle )
{
	ary::Slot_AutoPtr
            pSlot( ActiveParent().Create_Slot(i_nSlot) );
    if ( pSlot->Size() == 0 )
        return;

    aMemberAreas[ixPublic] = new S_AreaCo( o_rResult_public,
                                         i_sListLabel_public,
                                         i_sListTitle );
    aMemberAreas[ixProtected] = new S_AreaCo( o_rResult_protected,
                                            i_sListLabel_protected,
                                            i_sListTitle );
    aMemberAreas[ixPrivate] = new S_AreaCo( o_rResult_private,
                                          i_sListLabel_private,
                                          i_sListTitle );

    pSlot->StoreAt(*this);

    aMemberAreas[ixPublic]->PerformResult();
    aMemberAreas[ixProtected]->PerformResult();
    aMemberAreas[ixPrivate]->PerformResult();

    aMemberAreas[ixPublic] = 0;
    aMemberAreas[ixProtected] = 0;
    aMemberAreas[ixPrivate] = 0;
}

void
ChildList_Display::Run_MemberClasses( Area_Result &         o_rResult_public,
                                      Area_Result &         o_rResult_protected,
                                      Area_Result &         o_rResult_private,
                                      ary::SlotAccessId     i_nSlot,
                                      const char *          i_sListLabel_public,
                                      const char *          i_sListLabel_protected,
                                      const char *          i_sListLabel_private,
                                      const char *          i_sListTitle,
                                      ary::cpp::E_ClassKey  i_eFilter )
{
	ary::Slot_AutoPtr
            pSlot( ActiveParent().Create_Slot(i_nSlot) );
    if ( pSlot->Size() == 0 )
        return;

    aMemberAreas[ixPublic] = new S_AreaCo( o_rResult_public,
                                           i_sListLabel_public,
                                           i_sListTitle );
    aMemberAreas[ixProtected] = new S_AreaCo( o_rResult_protected,
                                              i_sListLabel_protected,
                                              i_sListTitle );
    aMemberAreas[ixPrivate] = new S_AreaCo( o_rResult_private,
                                            i_sListLabel_private,
                                            i_sListTitle );

    SetClassesFilter(i_eFilter);
    pSlot->StoreAt(*this);
    UnsetClassesFilter();

    aMemberAreas[ixPublic]->PerformResult();
    aMemberAreas[ixProtected]->PerformResult();
    aMemberAreas[ixPrivate]->PerformResult();

    aMemberAreas[ixPublic] = 0;
    aMemberAreas[ixProtected] = 0;
    aMemberAreas[ixPrivate] = 0;
}

void
ChildList_Display::do_Process( const ary::cpp::Namespace & i_rData )
{
    Write_ListItem( i_rData.LocalName(),
                    Path2ChildNamespace(i_rData.LocalName()),
                    ShortDocu( i_rData ),
                    GetArea().GetTable() );
}

void
ChildList_Display::do_Process( const ary::cpp::Class & i_rData )
{
    if ( Ce_IsInternal(i_rData) )
        return;

    if (peClassesFilter)
    {
     	if (*peClassesFilter != i_rData.ClassKey() )
            return;
    }

    String  sLink;
    if ( i_rData.Protection() == ary::cpp::PROTECT_global )
    {
        sLink = ClassFileName(i_rData.LocalName());

    }
    else
    {
        csv_assert( pActiveParentClass != 0 );
        sLink = Path2Child( ClassFileName(i_rData.LocalName()), pActiveParentClass->LocalName() );
    }

    if (peClassesFilter)
    {
        Write_ListItem( i_rData.LocalName(),
                        sLink,
                        ShortDocu( i_rData ),
                        GetArea(i_rData.Protection())
                            .GetTable() );
    }
    else
    {
        Write_ListItem( i_rData.LocalName(),
                        sLink,
                        ShortDocu( i_rData ),
                        GetArea(i_rData.Protection())
                            .GetTable(i_rData.ClassKey()) );
    }
}

void
ChildList_Display::do_Process( const ary::cpp::Enum & i_rData )
{
    if ( Ce_IsInternal(i_rData) )
        return;

    String  sLink;
    if ( i_rData.Protection() == ary::cpp::PROTECT_global )
    {
        sLink = EnumFileName(i_rData.LocalName());
    }
    else
    {
        csv_assert( pActiveParentClass != 0 );
        sLink = Path2Child( EnumFileName(i_rData.LocalName()),
                            pActiveParentClass->LocalName() );
    }

    Write_ListItem( i_rData.LocalName(),
                    sLink,
                    ShortDocu( i_rData ),
                    GetArea(i_rData.Protection()).GetTable() );
}

void
ChildList_Display::do_Process( const ary::cpp::Typedef & i_rData )
{
    if ( Ce_IsInternal(i_rData) )
        return;

    String  sLink;
    if ( i_rData.Protection() == ary::cpp::PROTECT_global )
    {
        sLink = TypedefFileName(i_rData.LocalName());
    }
    else
    {
        csv_assert( pActiveParentClass != 0 );
        sLink = Path2Child( TypedefFileName(i_rData.LocalName()),
                            pActiveParentClass->LocalName() );
    }

    Write_ListItem( i_rData.LocalName(),
                    sLink,
                    ShortDocu( i_rData ),
                    GetArea(i_rData.Protection()).GetTable() );
}

void
ChildList_Display::do_Process( const ary::cpp::Function & i_rData )
{
    if ( Ce_IsInternal(i_rData) )
        return;

    String  sLinkPrePath;
    if ( i_rData.Protection() == ary::cpp::PROTECT_global )
    {
        const ary::loc::File &
                rFile = Env().Gate().Locations().Find_File( i_rData.Location() );
        sLinkPrePath = HtmlFileName( "o-", rFile.LocalName() );
    }
    else
    {
        csv_assert( pActiveParentClass != 0 );
        sLinkPrePath = Path2Child( HtmlFileName( "o", "" ),
                                   pActiveParentClass->LocalName() );
    }

    // Out
    Table & rOut = GetArea(i_rData.Protection()).GetTable();
    TableRow * dpRow = new TableRow;
    rOut << dpRow;
    TableCell & rCell1 = dpRow->AddCell();

    rCell1
        << SyntaxText_PreName( i_rData, Env().Gate() )
        << new html::LineBreak;
    rCell1
        >> *new html::Link( OperationLink(
                                Env().Gate(),
                                i_rData.LocalName(),
                                i_rData.CeId(),
                                sLinkPrePath) )
            << i_rData.LocalName();
    rCell1
        << SyntaxText_PostName( i_rData, Env().Gate() );
    TableCell &
        rCell2 = dpRow->AddCell();
    rCell2
        << new WidthAttr("50%")
        << " ";

    pShortDocu_Display->Assign_Out( rCell2 );
    ShortDocu( i_rData ).StoreAt( *pShortDocu_Display );
    pShortDocu_Display->Unassign_Out();
}

void
ChildList_Display::do_Process( const ary::cpp::Variable & i_rData )
{
    if ( Ce_IsInternal(i_rData) )
        return;

    String  sLinkPrePath;
    if ( i_rData.Protection() == ary::cpp::PROTECT_global )
    {
        const ary::loc::File &
            rFile = Env().Gate().Locations().Find_File( i_rData.Location() );
        sLinkPrePath = HtmlFileName( "d-", rFile.LocalName() );
    }
    else
    {
        csv_assert( pActiveParentClass != 0 );
        sLinkPrePath = Path2Child( HtmlFileName( "d", "" ),
                                   pActiveParentClass->LocalName() );
    }

    TableRow * dpRow = new TableRow;
    GetArea(i_rData.Protection()).GetTable() << dpRow;

    *dpRow << new html::BgColorAttr("white");
    csi::xml::Element &
        rCell1 = dpRow->AddCell();

    dshelp::Get_LinkedTypeText( rCell1, Env(), i_rData.Type() );
    rCell1
        << " "
        >> *new html::Link( DataLink(i_rData.LocalName(), sLinkPrePath.c_str()) )
            >> *new html::Strong
                << i_rData.LocalName()
                << ";";

    TableCell & rShortDocu = dpRow->AddCell();
    pShortDocu_Display->Assign_Out( rShortDocu );
    ShortDocu( i_rData ).StoreAt( *pShortDocu_Display );
    pShortDocu_Display->Unassign_Out();
}

void
ChildList_Display::do_Process( const ary::cpp::EnumValue & i_rData )
{
    if ( Ce_IsInternal(i_rData) )
        return;

    Table & rOut = GetArea().GetTable();

    TableRow * dpRow = new TableRow;
    rOut << dpRow;

    *dpRow << new html::BgColorAttr("white");
    dpRow->AddCell()
        << new WidthAttr("20%")
        << new xml::AnAttribute("valign", "top")
        >> *new html::Label(i_rData.LocalName())
            >> *new html::Bold
                << i_rData.LocalName();

    TableCell & rValueDocu = dpRow->AddCell();
    pShortDocu_Display->Assign_Out( rValueDocu );
    i_rData.Docu().Accept( *pShortDocu_Display );
    pShortDocu_Display->Unassign_Out();
}

void
ChildList_Display::do_StartSlot()
{
}

void
ChildList_Display::do_FinishSlot()
{
}

const ary::cpp::Gate *
ChildList_Display::inq_Get_ReFinder() const
{
    return & Env().Gate();
}

void
ChildList_Display::Write_ListItem( const String &               i_sLeftText,
                                   const char *                 i_sLink,
                                   const ary::info::DocuText &  i_rRightText,
                                   csi::xml::Element &          o_rOut )
{
    TableRow * dpRow = new TableRow;
    o_rOut << dpRow;

    *dpRow << new html::BgColorAttr("white");
    dpRow->AddCell()
        << new WidthAttr("20%")
        >> *new html::Link( i_sLink )
                >> *new html::Bold
                        << i_sLeftText;

    TableCell & rShortDocu = dpRow->AddCell();
    pShortDocu_Display->Assign_Out( rShortDocu );
    i_rRightText.StoreAt( *pShortDocu_Display );
    pShortDocu_Display->Unassign_Out();
}

const ary::AryGroup &
ChildList_Display::ActiveParent()
{
    return pActiveParentClass != 0
                ?   static_cast< const ary::AryGroup& >(*pActiveParentClass)
                :   pActiveParentEnum != 0
                        ?   static_cast< const ary::AryGroup& >(*pActiveParentEnum)
                        :   static_cast< const ary::AryGroup& >(*Env().CurNamespace());
}

ProtectionArea &
ChildList_Display::GetArea()
{
    return pSglArea->aArea;
}

ProtectionArea &
ChildList_Display::GetArea( ary::cpp::E_Protection i_eProtection )
{
    switch ( i_eProtection )
    {
     	case ary::cpp::PROTECT_public:
                        return aMemberAreas[ixPublic]->aArea;
     	case ary::cpp::PROTECT_protected:
                        return aMemberAreas[ixProtected]->aArea;
     	case ary::cpp::PROTECT_private:
                        return aMemberAreas[ixPrivate]->aArea;
        default:
                        return pSglArea->aArea;
    }
}


//*******************               ********************//

ChildList_Display::
S_AreaCo::S_AreaCo( Area_Result &       o_rResult,
                    const char *        i_sLabel,
                    const char *        i_sTitle )
    :   aArea(i_sLabel, i_sTitle),
        pResult(&o_rResult)
{
}

ChildList_Display::
S_AreaCo::~S_AreaCo()
{
}

void
ChildList_Display::
S_AreaCo::PerformResult()
{
    bool bUsed = aArea.WasUsed_Area();
    pResult->rChildrenExist = bUsed;
    if ( bUsed )
    {
        Create_ChildListLabel( Out(), aArea.Label() );

        if ( aArea.Size() == 1 )
        {
            Out() << aArea.ReleaseTable();
        }
        else
        {
         	Table * pTable = aArea.ReleaseTable( ary::cpp::CK_class );
            if (pTable != 0)
                Out() << pTable;
         	pTable = aArea.ReleaseTable( ary::cpp::CK_struct );
            if (pTable != 0)
                Out() << pTable;
         	pTable = aArea.ReleaseTable( ary::cpp::CK_union );
            if (pTable != 0)
                Out() << pTable;
        }
    }
}
