/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This 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 library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: IBM Corporation
 *
 *  Copyright: 2008 by IBM Corporation
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
/*************************************************************************
 * @file
 *  For LWP filter architecture prototype
 ************************************************************************/
/*************************************************************************
 * Change History
 Jan 2005			Created
 ************************************************************************/

#include "lwpfribptr.hxx"

#include "lwpfribheader.hxx"
#include "lwpfribtext.hxx"
#include "lwppara.hxx"
#include "lwpstory.hxx"
#include "xfilter/xftextspan.hxx"
#include "xfilter/xftextcontent.hxx"
#include "xfilter/xftabstop.hxx"
#include "xfilter/xflinebreak.hxx"
#include "lwpfribsection.hxx"
#include "lwpsection.hxx"
#include "lwpfribbreaks.hxx"
#include "lwpfribframe.hxx"
#include "lwpfribtable.hxx"
#include "xfilter/xfstylemanager.hxx"
#include "lwphyperlinkmgr.hxx"
#include "xfilter/xfhyperlink.hxx"
#include "lwpfootnote.hxx"
#include "lwpnotes.hxx"
#include "lwpfribmark.hxx"
#include "xfilter/xfchange.hxx"
#include "lwpchangemgr.hxx"
#include "lwpglobalmgr.hxx"


LwpFribPtr::LwpFribPtr()
    : m_pFribs(NULL),m_pXFPara(NULL),m_pPara(NULL)
{}

LwpFribPtr::~LwpFribPtr()
{
    LwpFrib* pNextFrib = m_pFribs;
    LwpFrib* pCurFrib = m_pFribs;
    while(pCurFrib)
    {
        pNextFrib = pCurFrib -> GetNext();
        delete pCurFrib;
        pCurFrib = pNextFrib;
    }
}

void LwpFribPtr::ReadPara(LwpObjectStream* pObjStrm)
{
    sal_uInt8 FribTag=0;
    sal_uInt8 FribType;
    sal_uInt8 FribEditor;
    BOOL ProblemFrib;

    LwpFrib* pCurFrib = m_pFribs = NULL;
    for(;;)
    {
        ProblemFrib = FALSE;
        // Get the frib type
        pObjStrm->QuickRead(&FribTag, sizeof(FribTag));

        FribType = FribTag & ~FRIB_TAG_TYPEMASK;

        // Stop when we hit Elvis
        if (FribType == FRIB_TAG_ELVIS)
            break;

        // skip the editor ID
        //pObjStrm->SeekRel(sizeof(sal_uInt8));
        pObjStrm->QuickRead(&FribEditor, sizeof(FribEditor));
        if( FribType != FT_MAXIMUM )
        {
            LwpFrib* pFrib = LwpFrib::CreateFrib( m_pPara, pObjStrm, FribTag,FribEditor);
            if(!m_pFribs)
            {
                m_pFribs = pFrib;
            }
            if(pCurFrib)
            {
                pCurFrib->SetNext(pFrib);
            }
            else//frist frib in the para,add by  2/1
            {
                if (pFrib->GetType() == FRIB_TAG_TEXT)
                {
                    LwpFribText* pText = static_cast<LwpFribText*>(pFrib);
                    if (pFrib->GetModifiers())
                        m_pPara->SetFirstFrib(pText->GetText(),pText->GetModifiers()->FontID);
                    else
                        m_pPara->SetFirstFrib(pText->GetText(),0);
                }
            }
            pCurFrib = pFrib;
        }
        else
            ProblemFrib = TRUE;
    }
}

/*String LwpFribPtr::GetText()
{
    LwpFrib* pFrib = m_pFribs;
    String content;
    while(pFrib)
    {
        if(pFrib->GetType() == FRIB_TAG_TEXT)
        {
            content+= static_cast<LwpFribText*>(pFrib)->GetText();
        }
        pFrib = pFrib->GetNext();
    }
    return (content);
}*/

#include "lwpdropcapmgr.hxx"
void LwpFribPtr::XFConvert()
{
    LwpFrib* pFrib = m_pFribs;
    while(pFrib)
    {
        sal_uInt8 nFribType = pFrib->GetType();
        sal_Bool bRevisionFlag = pFrib->GetRevisionFlag();
        sal_uInt8 nRevisionType;
        OUString sChangeID;
        if (bRevisionFlag)
        {
            if ( nFribType!= FRIB_TAG_TABLE && nFribType != FRIB_TAG_FIELD
                    && nFribType != FRIB_TAG_FRAME)
            {
                nRevisionType = pFrib->GetRevisionType();
                LwpGlobalMgr* pGlobal = LwpGlobalMgr::GetInstance();
                LwpChangeMgr* pChangeMgr = pGlobal->GetLwpChangeMgr();
                sChangeID = pChangeMgr->GetChangeID(pFrib);
                if (sChangeID.getLength())
                {
                ///	if (nRevisionType == LwpFrib::REV_INSERT)
                ///	{
                        XFChangeStart* pChangeStart = new XFChangeStart;
                        pChangeStart->SetChangeID(sChangeID);
                        m_pXFPara->Add(pChangeStart);
                ///	}
                ///	else if (nRevisionType == LwpFrib::REV_DELETE)
                ///	{
                ///		XFChange* pChange = new XFChange;
                ///		pChange->SetChangeID(sChangeID);
                ///		m_pXFPara->Add(pChange);
                ///		pFrib = pFrib->GetNext();
                ///		continue;
                ///	}
                }
            }
        }

            switch(nFribType)
            {
        case FRIB_TAG_TEXT:
        {
            LwpFribText* textFrib= static_cast<LwpFribText*>(pFrib);
            textFrib->XFConvert(m_pXFPara,m_pPara->GetStory());
        }
            break;
        case FRIB_TAG_TAB:
        {
            LwpFribTab* tabFrib = static_cast<LwpFribTab*>(pFrib);
            if (pFrib->m_ModFlag)
            {
                XFTextSpan *pSpan = new XFTextSpan();
                pSpan->SetStyleName(tabFrib->GetStyleName());
                XFTabStop *pTab = new XFTabStop();
                pSpan->Add(pTab);
                m_pXFPara->Add(pSpan);
            }
            else
            {
                XFTabStop *pTab = new XFTabStop();
                m_pXFPara->Add(pTab);
            }
        }
            break;
        case FRIB_TAG_SECTION:
        {
            LwpFribSection* pSectionFrib = static_cast<LwpFribSection*>(pFrib);
            pSectionFrib->ParseSection();
        }
        break;

        case FRIB_TAG_PAGEBREAK:
        {
            LwpFribPageBreak* pPageBreak = static_cast<LwpFribPageBreak*>(pFrib);
            LwpPageLayout* pLayout = static_cast<LwpPageLayout*>(pPageBreak->GetLayout()->obj());
            if(pLayout)
            {
                pPageBreak->ParseLayout();
            }
            else
            {
                if (pPageBreak->IsLastFrib() == sal_True)
                {
                    m_pXFPara->SetStyleName( pPageBreak->GetStyleName() );
                }
                else
                {
                    //parse pagebreak
                    XFParagraph *pPara = new XFParagraph();
                    pPara->SetStyleName(pFrib->GetStyleName());
                    SetXFPara(pPara);
                    m_pPara->AddXFContent(pPara);
                }
            }
        }
            break;
        case FRIB_TAG_COLBREAK:
        {
            XFParagraph *pPara = new XFParagraph();
            pPara->SetStyleName(pFrib->GetStyleName());
            SetXFPara(pPara);
            m_pPara->AddXFContent(pPara);
        }
            break;
        case FRIB_TAG_LINEBREAK:
        {
            XFLineBreak *pLineBreak = new XFLineBreak();
            m_pXFPara->Add(pLineBreak);
        }
            break;
        case FRIB_TAG_UNICODE: //fall through
        case FRIB_TAG_UNICODE2: //fall through
        case FRIB_TAG_UNICODE3: //fall through
        {
            LwpFribUnicode* unicodeFrib= static_cast<LwpFribUnicode*>(pFrib);
            unicodeFrib->XFConvert(m_pXFPara,m_pPara->GetStory());
        }
            break;
        case FRIB_TAG_HARDSPACE:
        {
            rtl::OUString sHardSpace(sal_Unicode(0x00a0));
            LwpHyperlinkMgr* pHyperlink =
                    m_pPara->GetStory()->GetHyperlinkMgr();
            if (pHyperlink->GetHyperlinkFlag())
                pFrib->ConvertHyperLink(m_pXFPara,pHyperlink,sHardSpace);
            else
                pFrib->ConvertChars(m_pXFPara,sHardSpace);
        }
            break;
        case FRIB_TAG_SOFTHYPHEN:
        {
            rtl::OUString sSoftHyphen(sal_Unicode(0x00ad));
            pFrib->ConvertChars(m_pXFPara,sSoftHyphen);
        }
            break;
        case FRIB_TAG_FRAME:
        {
            LwpFribFrame* frameFrib= static_cast<LwpFribFrame*>(pFrib);
            LwpObject* pLayout = frameFrib->GetLayout();
            if (pLayout->GetTag() == VO_DROPCAPLAYOUT)
            {
                m_pPara->GetFoundry()->GetDropcapMgr()->SetXFPara(m_pXFPara);
                //LwpObject* pDropCap = frameFrib->GetLayout();
                //pDropCap ->XFConvert(m_pXFPara);
            }
            //pLayout->XFConvert(m_pXFPara);
            frameFrib->XFConvert(m_pXFPara);
        }
            break;
        case FRIB_TAG_CHBLOCK:
        {
            LwpFribCHBlock* chbFrib = static_cast<LwpFribCHBlock*>(pFrib);
            chbFrib->XFConvert(m_pXFPara,m_pPara->GetStory());
        }
            break;
        case FRIB_TAG_TABLE:
        {
            LwpFribTable* tableFrib = static_cast<LwpFribTable*>(pFrib);
            //tableFrib->XFConvert(m_pPara->GetXFContainer());
            tableFrib->XFConvert(m_pXFPara);
        }
            break;
        case FRIB_TAG_BOOKMARK:
        {
            LwpFribBookMark* bookmarkFrib = static_cast<LwpFribBookMark*>(pFrib);
            bookmarkFrib->XFConvert(m_pXFPara);
        }
        break;
        case FRIB_TAG_FOOTNOTE:
        {
            LwpFribFootnote* pFootnoteFrib = static_cast<LwpFribFootnote*>(pFrib);
            pFootnoteFrib->XFConvert(m_pXFPara);
            break;
        }
        case FRIB_TAG_FIELD:
        {
            LwpFribField* fieldFrib = static_cast<LwpFribField*>(pFrib);
            fieldFrib->XFConvert(m_pXFPara);
            break;
        }
        case FRIB_TAG_NOTE:
        {
            LwpFribNote* pNoteFrib = static_cast<LwpFribNote*>(pFrib);
            pNoteFrib->XFConvert(m_pXFPara);
            break;
        }
        case FRIB_TAG_PAGENUMBER:
        {
            LwpFribPageNumber* pagenumFrib = static_cast<LwpFribPageNumber*>(pFrib);
            pagenumFrib->XFConvert(m_pXFPara);
            break;
        }
        case FRIB_TAG_DOCVAR:
        {
            LwpFribDocVar* docFrib = static_cast<LwpFribDocVar*>(pFrib);
            docFrib->XFConvert(m_pXFPara);
            break;
        }
        case FRIB_TAG_RUBYMARKER:
        {
            LwpFribRubyMarker* rubyFrib = static_cast<LwpFribRubyMarker*>(pFrib);
            rubyFrib->XFConvert(m_pXFPara);
            break;
        }
        case FRIB_TAG_RUBYFRAME:
        {
            LwpFribRubyFrame* rubyfrmeFrib = static_cast<LwpFribRubyFrame*>(pFrib);
            rubyfrmeFrib->XFConvert(m_pXFPara);
            break;
        }
        default :
            break;
        }

        if (bRevisionFlag )//&& pFrib->GetRevisionType() == LwpFrib::REV_INSERT)
        {
            if (nFribType!= FRIB_TAG_TABLE && nFribType != FRIB_TAG_FIELD
                    && nFribType != FRIB_TAG_FRAME)
            {
                if (sChangeID.getLength())
                {
                    XFChangeEnd* pChangeEnd = new XFChangeEnd;
                    pChangeEnd->SetChangeID(sChangeID);
                    m_pXFPara->Add(pChangeEnd);
                }
            }
        }
        pFrib = pFrib->GetNext();
    }

}

void LwpFribPtr::FindLayouts()
{
    LwpFrib* pFrib = m_pFribs;
    while(pFrib)
    {
        switch(pFrib->GetType())
        {
            case FRIB_TAG_SECTION:
            {
                LwpFribSection* pSectionFrib = static_cast<LwpFribSection*>(pFrib);
                LwpSection* pSection = pSectionFrib->GetSection();
                if(pSection)
                {
                    LwpPageLayout* pLayout = pSection->GetPageLayout();
                    if(pLayout)
                    {
                        LwpLayout::UseWhenType eSectionType = pLayout->GetUseWhenType();
                        if(eSectionType==LwpLayout::StartWithinColume)
                        {
                            //StartWithinColume type not support now
                            break;
                        }
                        LwpStory* pStory = static_cast<LwpStory*>(m_pPara->GetStoryID()->obj());
                        pStory->AddPageLayout(pSection->GetPageLayout());
                    }
                }

                break;
            }
            case FRIB_TAG_PAGEBREAK:
            {
                LwpFribPageBreak* pPageBreak = static_cast<LwpFribPageBreak*>(pFrib);
                LwpPageLayout* pLayout = static_cast<LwpPageLayout*>(pPageBreak->GetLayout()->obj());
                if(pLayout)
                {
                    LwpStory* pStory = static_cast<LwpStory*>(m_pPara->GetStoryID()->obj());
                    pStory->AddPageLayout(pLayout);
                }
                break;
            }
            default:
                break;
        }
        pFrib = pFrib->GetNext();
    }
}
/**************************************************************************
 * @descr:  Whether has a frib which type is nType
 * @param:
 * @param:
 * @return:
**************************************************************************/
LwpFrib* LwpFribPtr::HasFrib(sal_uInt8 nType)
{
    LwpFrib* pFrib = m_pFribs;
    while(pFrib)
    {
        if(pFrib->GetType()==nType)
        {
            return pFrib;
        }
        pFrib = pFrib->GetNext();
    }
    return NULL;
}

void LwpFribPtr::GatherAllText()
{
    LwpFrib* pFrib = m_pFribs;
    while(pFrib)
    {
        switch(pFrib->GetType())
        {
        case FRIB_TAG_TEXT:
        {
            OUString sText = static_cast<LwpFribText*>(pFrib)->GetText();
            m_pPara->SetAllText(sText);
            break;
        }
        case FRIB_TAG_UNICODE: //fall through
        case FRIB_TAG_UNICODE2: //fall through
        case FRIB_TAG_UNICODE3: //fall through	:
        {
            OUString sText = static_cast<LwpFribText*>(pFrib)->GetText();
            m_pPara->SetAllText(sText);
            break;
        }
        default :
            break;
    }
        pFrib = pFrib->GetNext();
    }
}

void LwpFribPtr::RegisterStyle()
{
    LwpFrib* pFrib = m_pFribs;
    while(pFrib)
    {
        switch(pFrib->GetType())
        {
        case FRIB_TAG_TEXT:
        {
            pFrib->RegisterStyle(m_pPara->GetFoundry());
            OUString sText = static_cast<LwpFribText*>(pFrib)->GetText();
            ProcessDropcap(m_pPara->GetStory(), pFrib,sText.getLength());
            break;
        }
        case FRIB_TAG_TAB:
            pFrib->RegisterStyle(m_pPara->GetFoundry());
            break;
        case FRIB_TAG_SECTION:
            {
                //section registerstyle here;
                LwpFribSection* pSectionFrib = static_cast<LwpFribSection*>(pFrib);
                pSectionFrib->RegisterSectionStyle();
                //for bullet
                pSectionFrib->SetSectionName();
            }
            break;
        case FRIB_TAG_PAGEBREAK:
        {
            LwpFribPageBreak* breakFrib = static_cast<LwpFribPageBreak*>(pFrib);
            breakFrib->RegisterBreakStyle(m_pPara);
        }
            break;
        case FRIB_TAG_COLBREAK:
        {
            LwpFribColumnBreak* breakFrib = static_cast<LwpFribColumnBreak*>(pFrib);
            breakFrib->RegisterBreakStyle(m_pPara);
        }
            break;
        case FRIB_TAG_UNICODE: //fall through
        case FRIB_TAG_UNICODE2: //fall through
        case FRIB_TAG_UNICODE3: //fall through	:
        {
            pFrib->RegisterStyle(m_pPara->GetFoundry());
            OUString sText = static_cast<LwpFribUnicode*>(pFrib)->GetText();
            ProcessDropcap(m_pPara->GetStory(), pFrib,sText.getLength());
            break;
        }
        case FRIB_TAG_HARDSPACE:
            pFrib->RegisterStyle(m_pPara->GetFoundry());
            ProcessDropcap(m_pPara->GetStory(),pFrib,1);
            break;
        case FRIB_TAG_SOFTHYPHEN:
            pFrib->RegisterStyle(m_pPara->GetFoundry());
            break;
        case FRIB_TAG_FRAME:
        {
            LwpFribFrame* frameFrib = static_cast<LwpFribFrame*>(pFrib);
            frameFrib->SetParaDropcap(m_pPara);
            frameFrib->RegisterStyle(m_pPara->GetFoundry());
            //register framelayout style, ,03/09/2005
            //frameFrib->GetLayout()->RegisterStyle();
                }
                    break;
                case FRIB_TAG_CHBLOCK:
                    break;
                case FRIB_TAG_TABLE:
                {
                    LwpFribTable* tableFrib = static_cast<LwpFribTable*>(pFrib);
                    tableFrib->RegisterStyle();
                }
                    break;
        case FRIB_TAG_FOOTNOTE:
        {
            LwpFribFootnote* pFribFootnote = static_cast<LwpFribFootnote*>(pFrib);
            pFribFootnote->RegisterStyle();
        }
            break;
        case FRIB_TAG_NOTE:
        {
            LwpFribNote* pNoteFrib = static_cast<LwpFribNote*>(pFrib);
            pNoteFrib->RegisterStyle();
            break;
        }
        case FRIB_TAG_PAGENUMBER:
        {
            pFrib->RegisterStyle(m_pPara->GetFoundry());
            break;
        }
        case FRIB_TAG_DOCVAR:
        {
            LwpFribDocVar* docFrib = static_cast<LwpFribDocVar*>(pFrib);
            docFrib->RegisterStyle(m_pPara->GetFoundry());
            break;
        }
        case FRIB_TAG_FIELD:
        {
            LwpFribField* fieldFrib = static_cast<LwpFribField*>(pFrib);
            fieldFrib->RegisterStyle(m_pPara->GetFoundry());
            break;
        }
        case FRIB_TAG_BOOKMARK:
        {
            LwpFribBookMark* bookmarkFrib = static_cast<LwpFribBookMark*>(pFrib);
            bookmarkFrib->RegisterStyle(m_pPara->GetFoundry());
            break;
        }
        case FRIB_TAG_RUBYFRAME:
        {
            LwpFribRubyFrame* rubyfrmeFrib = static_cast<LwpFribRubyFrame*>(pFrib);
            rubyfrmeFrib->RegisterStyle(m_pPara->GetFoundry());
            break;
        }
        default :
            break;
        }
        if (pFrib->GetRevisionFlag() && pFrib->GetType()!= FRIB_TAG_FIELD)
        {
            LwpGlobalMgr* pGlobal = LwpGlobalMgr::GetInstance();
            LwpChangeMgr* pChangeMgr = pGlobal->GetLwpChangeMgr();
            pChangeMgr->AddChangeFrib(pFrib);
        }

        pFrib = pFrib->GetNext();
    }
}

void LwpFribPtr::ProcessDropcap(LwpStory* pStory,LwpFrib* pFrib,sal_uInt32 nLen)
{
    if (pStory)
    {
        if (pStory->GetDropcapFlag() == sal_True)
        {
            XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
            XFTextStyle* pFribStyle = pXFStyleManager->FindTextStyle(pFrib->GetStyleName());
            pFribStyle->GetFont()->SetFontSize(0);

            LwpObject*  pObj= pStory->GetLayoutsWithMe()->GetOnlyLayout()->obj();
            if (pObj)
                static_cast<LwpDropcapLayout*>(pObj)->SetChars(nLen);
        }
    }
}
/**
 * @descr:  If the position of pPreLayout is earlier than pNextLayout, return true, or return false, defalut return true
 *
*/
sal_Bool LwpFribPtr::ComparePagePosition(LwpVirtualLayout* pPreLayout, LwpVirtualLayout* pNextLayout)
{
    if(!pPreLayout || !pNextLayout)
        return sal_True;

    LwpFrib* pFrib = m_pFribs;
    LwpVirtualLayout* pLayout = NULL;
    while(pFrib)
    {
        switch(pFrib->GetType())
            {
            case FRIB_TAG_SECTION:
            {
                LwpFribSection* pSectionFrib = static_cast<LwpFribSection*>(pFrib);
                LwpSection* pSection = pSectionFrib->GetSection();
                if(pSection)
                {
                    pLayout = pSection->GetPageLayout();
                }

                break;
            }
            case FRIB_TAG_PAGEBREAK:
            {
                LwpFribPageBreak* pPageBreak = static_cast<LwpFribPageBreak*>(pFrib);
                pLayout = static_cast<LwpVirtualLayout*>(pPageBreak->GetLayout()->obj());
                break;
            }
            default:
                break;
        }

        if(pLayout)
        {
            if(pPreLayout == pLayout)
                return sal_True;
            if(pNextLayout == pLayout)
                return sal_False;
        }
        pFrib = pFrib->GetNext();
    }

    return sal_True;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
