/**************************************************************
 * 
 * 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 "hfi_xrefpage.hxx"


// NOT FULLY DEFINED SERVICES
#include <ary/idl/i_ce.hxx>
#include <ary/idl/i_gate.hxx>
#include <ary/idl/ip_ce.hxx>
#include <toolkit/hf_title.hxx>
#include "hfi_navibar.hxx"
#include "hfi_typetext.hxx"
#include "hi_env.hxx"


namespace
{

const String
    C_sTitleStart("uses of ");
const String
    C_sCRLF("\n");
const String
    C_sDevMan("References in Developers Guide");

}   // anonymous namespace



HF_IdlXrefs::HF_IdlXrefs( Environment &         io_rEnv,
                          Xml::Element &        o_rOut,
                          const String &        i_prefix,
                          const client &        i_ce )
    :   HtmlFactory_Idl(io_rEnv, &o_rOut),
        rContentDirectory(*new Html::Paragraph),
        pClient(&i_ce)
{
    produce_Main(i_prefix, i_ce);
}

HF_IdlXrefs::~HF_IdlXrefs()
{
}

void
HF_IdlXrefs::Write_ManualLinks( const client &  i_ce ) const
{
    const StringVector &
        rLinks2Refs = i_ce.Secondaries().Links2RefsInManual();
    if ( rLinks2Refs.size() == 0 )
    {
        rContentDirectory
            << C_sDevMan
            << new Html::LineBreak
            << C_sCRLF;
        return;
    }


    rContentDirectory
        >> *new Html::Link("#devmanrefs")
            << C_sDevMan
            << new Html::LineBreak
            << C_sCRLF;

    HF_SubTitleTable
        aList(CurOut(), "devmanrefs", C_sDevMan, 1);
    Xml::Element &
        rOutCell = aList.Add_Row() >>* new Html::TableCell;

    csv_assert(rLinks2Refs.size() % 2 == 0);
    for ( StringVector::const_iterator it = rLinks2Refs.begin();
          it != rLinks2Refs.end();
          ++it )
    {
        Xml::Element &
            rLink = rOutCell >> *new Html::Link( Env().Link2Manual(*it));
        if ( (*(it+1)).empty() )

            // HACK KORR_FUTURE
            // Research what happens with manual links which contain normal characters
            // in non-utf-8 texts. And research, why utfF-8 does not work here.
            rLink << new Xml::XmlCode(*it);
        else
            // HACK KORR_FUTURE, see above.
            rLink << new Xml::XmlCode( *(it+1) );
        rOutCell
            << new Html::LineBreak
            << C_sCRLF;
        ++it;
    }   // end for
}

void
HF_IdlXrefs::Produce_List( const char *        i_title,
                           const char *        i_label,
                           ce_list &           i_iterator ) const
{
    if (NOT i_iterator)
    {
        rContentDirectory
            << i_title
            << new Html::LineBreak
            << C_sCRLF;
        return;
    }

    csv_assert(*i_label == '#');

    rContentDirectory
        >> *new Html::Link(i_label)
            << i_title
            << new Html::LineBreak
            << C_sCRLF;

    HF_SubTitleTable
        aList(CurOut(), i_label+1, i_title, 1);
    Xml::Element &
        rOutCell = aList.Add_Row() >>* new Html::TableCell;
    HF_IdlTypeText
        aTypeWriter(Env(), rOutCell, true, pClient);
    for ( ce_list & it = i_iterator; it; ++it )
    {
        aTypeWriter.Produce_byData(*it);
        rOutCell << new Html::LineBreak;
    }   // end for
}

void
HF_IdlXrefs::Produce_Tree(  const char *        i_title,
                            const char *        i_label,
                            const client &      i_ce,
                            F_GET_SUBLIST       i_sublistcreator ) const
{
    dyn_ce_list pResult;
    (*i_sublistcreator)(pResult, i_ce);

    if (NOT (*pResult).operator bool())
    {
        rContentDirectory
            << i_title
            << new Html::LineBreak
            << C_sCRLF;
        return;
    }

    csv_assert(*i_label == '#');

    rContentDirectory
        >> *new Html::Link(i_label)
            << i_title
            << new Html::LineBreak
            << C_sCRLF;

    HF_SubTitleTable
        aList(CurOut(), i_label+1, i_title, 1);
    Xml::Element &
        rOut = aList.Add_Row()
                    >>* new Html::TableCell
                        >> *new csi::xml::AnElement("pre")
                            << new csi::html::StyleAttr("font-family:monospace;");

    recursive_make_ListInTree( rOut,
							   0,
							   i_ce,
							   *pResult,
							   i_sublistcreator );
}

void
HF_IdlXrefs::produce_Main( const String &        i_prefix,
                           const client &        i_ce ) const
{
    make_Navibar(i_ce);

    HF_TitleTable
        aTitle(CurOut());
    StreamLock sl(200);
    aTitle.Produce_Title( sl()
						  << C_sTitleStart
						  << i_prefix
						  << " "
						  << i_ce.LocalName()
						  << c_str );

    aTitle.Add_Row() << &rContentDirectory;
    sl().reset();
    rContentDirectory
        >> *new Html::Link( sl()    << i_ce.LocalName()
						            << ".html"
						            << c_str )
            >> *new Html::Bold
                << "back to "
                << i_prefix
                << " "
                << i_ce.LocalName();
    rContentDirectory
        << new Html::LineBreak
        << new Html::LineBreak
        << C_sCRLF;

    CurOut() << new Html::HorizontalLine();
}

void
HF_IdlXrefs::make_Navibar( const client & i_ce ) const
{
    HF_IdlNavigationBar
        aNaviBar(Env(), CurOut());
    aNaviBar.Produce_CeXrefsMainRow(i_ce);
    CurOut() << new Html::HorizontalLine();
}

void
HF_IdlXrefs::recursive_make_ListInTree( Xml::Element &      o_rDisplay,
										uintt               i_level,
										const client &      i_ce,
										ce_list &           i_iterator,
										F_GET_SUBLIST       i_sublistcreator ) const
{
    const char * sLevelIndentation = "    ";

    HF_IdlTypeText
        aTypeWriter(Env(), o_rDisplay, true, &i_ce);
    for ( ; i_iterator.operator bool(); ++i_iterator )
    {
        for (uintt i = 0; i < i_level; ++i)
        {
            o_rDisplay << sLevelIndentation;
        }   // end for

        aTypeWriter.Produce_byData(*i_iterator);
        o_rDisplay << C_sCRLF;

        dyn_ce_list     pResult;
        const client &  rCe = Env().Gate().Ces().Find_Ce(*i_iterator);
        (*i_sublistcreator)(pResult, rCe);
        if ( (*pResult).operator bool() )
        {
            recursive_make_ListInTree( o_rDisplay,
	    							   i_level + 1,
	    							   rCe,
		    						   *pResult,
			    					   i_sublistcreator );
        }
    }   // end for
}
