/**************************************************************
 *
 * 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_editeng.hxx"
#include<rtl/ustring.hxx>
#include <tools/shl.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/svapp.hxx>
#include <vcl/msgbox.hxx>
#include <tools/debug.hxx>
#include <svtools/langtab.hxx>

#ifndef __RSC
#include <tools/errinf.hxx>
#endif
#include <editeng/unolingu.hxx>
#include <linguistic/lngprops.hxx>
#include <com/sun/star/frame/XStorable.hpp>

#include <map>

#include <editeng/svxenum.hxx>
#include <editeng/splwrap.hxx>      // Der Wrapper
#include <editeng/edtdlg.hxx>
#include <editeng/eerdll.hxx>
#include <editeng/editrids.hrc>
#include <editeng/editids.hrc>
#include <editeng/editerr.hxx>

#define WAIT_ON() if(pWin != NULL) { pWin->EnterWait(); }

#define WAIT_OFF() if(pWin != NULL) { pWin->LeaveWait(); }

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::linguistic2;


// misc functions ---------------------------------------------

void SvxPrepareAutoCorrect( String &rOldText, String &rNewText )
{
	// This function should be used to strip (or add) trailing '.' from
	// the strings before passing them on to the autocorrect function in
	// order that the autocorrect function will hopefully
	// works properly with normal words and abbreviations (with trailing '.')
	// independ of if they are at the end of the sentence or not.
	//
	// rOldText: text to be replaced
	// rNewText: replacement text

	xub_StrLen	nOldLen = rOldText.Len(),
				nNewLen = rNewText.Len();
	if (nOldLen && nNewLen)
	{
		sal_Bool bOldHasDot = sal_Unicode( '.' ) == rOldText.GetChar( nOldLen - 1 ),
			 bNewHasDot = sal_Unicode( '.' ) == rNewText.GetChar( nNewLen - 1 );
		if (bOldHasDot && !bNewHasDot
			/*this is: !(bOldHasDot && bNewHasDot) && bOldHasDot*/)
			rOldText.Erase( nOldLen - 1 );
	}
}

// -----------------------------------------------------------------------

#define SVX_LANG_NEED_CHECK			0
#define SVX_LANG_OK					1
#define SVX_LANG_MISSING			2
#define SVX_LANG_MISSING_DO_WARN	3

#define SVX_FLAGS_NEW


struct lt_LanguageType
{
    bool operator()( LanguageType n1, LanguageType n2 ) const
    {
        return n1 < n2;
    }
};

typedef std::map< LanguageType, sal_uInt16, lt_LanguageType >   LangCheckState_map_t;

static LangCheckState_map_t & GetLangCheckState()
{
    static LangCheckState_map_t aLangCheckState;
    return aLangCheckState;
}

void SvxSpellWrapper::ShowLanguageErrors()
{
    // display message boxes for languages not available for
    // spellchecking or hyphenation
    LangCheckState_map_t &rLCS = GetLangCheckState();
    LangCheckState_map_t::iterator aIt( rLCS.begin() );
    while (aIt != rLCS.end())
	{
        LanguageType nLang = aIt->first;
        sal_uInt16   nVal  = aIt->second;
		sal_uInt16 nTmpSpell = nVal & 0x00FF;
		sal_uInt16 nTmpHyph  = (nVal >> 8) & 0x00FF;

		if (SVX_LANG_MISSING_DO_WARN == nTmpSpell)
		{
			String aErr( SvtLanguageTable::GetLanguageString( nLang ) );
			ErrorHandler::HandleError(
				*new StringErrorInfo( ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr ) );
			nTmpSpell = SVX_LANG_MISSING;
		}
		if (SVX_LANG_MISSING_DO_WARN == nTmpHyph)
		{
			String aErr( SvtLanguageTable::GetLanguageString( nLang ) );
			ErrorHandler::HandleError(
				*new StringErrorInfo( ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr ) );
			nTmpHyph = SVX_LANG_MISSING;
		}

        rLCS[ nLang ] = (nTmpHyph << 8) | nTmpSpell;
        ++aIt;
	}

}

SvxSpellWrapper::~SvxSpellWrapper()
{
}

/*--------------------------------------------------------------------
 *	Beschreibung: Ctor, die Pruefreihenfolge wird festgelegt
 *
 *  !bStart && !bOtherCntnt:	BODY_END,	BODY_START,	OTHER
 *  !bStart && bOtherCntnt:		OTHER,		BODY
 *  bStart && !bOtherCntnt:		BODY_END,	OTHER
 *  bStart && bOtherCntnt:		OTHER
 *
 --------------------------------------------------------------------*/

SvxSpellWrapper::SvxSpellWrapper( Window* pWn,
	Reference< XSpellChecker1 >  &xSpellChecker,
	const sal_Bool bStart, const sal_Bool bIsAllRight,
	const sal_Bool bOther, const sal_Bool bRevAllow ) :

	pWin		( pWn ),
	xSpell		( xSpellChecker ),
	mpTextObj( NULL),
	bOtherCntnt	( bOther ),
	bDialog		( sal_False ),
	bHyphen		( sal_False ),
	bAuto		( sal_False ),
	bStartChk	( bOther ),
    bRevAllowed ( bRevAllow ),
    bAllRight   ( bIsAllRight )
{
	Reference< beans::XPropertySet >  xProp( SvxGetLinguPropertySet() );
	sal_Bool bWrapReverse = xProp.is() ?
		*(sal_Bool*)xProp->getPropertyValue(
			::rtl::OUString::createFromAscii(UPN_IS_WRAP_REVERSE) ).getValue()
		: sal_False;
	bReverse = bRevAllow && bWrapReverse;
	bStartDone = bOther || ( !bReverse && bStart );
	bEndDone   = bReverse && bStart && !bOther;
}

// -----------------------------------------------------------------------

SvxSpellWrapper::SvxSpellWrapper( Window* pWn,
		Reference< XHyphenator >  &xHyphenator,
		const sal_Bool bStart, const sal_Bool bOther ) :
	pWin		( pWn ),
	xHyph		( xHyphenator ),
	mpTextObj( NULL),
	bOtherCntnt	( bOther ),
	bDialog		( sal_False ),
	bHyphen		( sal_False ),
	bAuto		( sal_False ),
	bReverse	( sal_False ),
	bStartDone	( bOther || ( !bReverse && bStart ) ),
	bEndDone	( bReverse && bStart && !bOther ),
	bStartChk	( bOther ),
    bRevAllowed ( sal_False ),
    bAllRight   ( sal_True )
{
}

// -----------------------------------------------------------------------

sal_Int16 SvxSpellWrapper::CheckSpellLang(
		Reference< XSpellChecker1 > xSpell, sal_Int16 nLang)
{
    LangCheckState_map_t &rLCS = GetLangCheckState();

    LangCheckState_map_t::iterator aIt( rLCS.find( nLang ) );
    sal_uInt16 nVal = aIt == rLCS.end() ? SVX_LANG_NEED_CHECK : aIt->second;

    if (aIt == rLCS.end())
        rLCS[ nLang ] = nVal;

	if (SVX_LANG_NEED_CHECK == (nVal & 0x00FF))
	{
		sal_uInt16 nTmpVal = SVX_LANG_MISSING_DO_WARN;
		if (xSpell.is()  &&  xSpell->hasLanguage( nLang ))
			nTmpVal = SVX_LANG_OK;
		nVal &= 0xFF00;
		nVal |= nTmpVal;

        rLCS[ nLang ] = nVal;
	}

    return (sal_Int16) nVal;
}

sal_Int16 SvxSpellWrapper::CheckHyphLang(
		Reference< XHyphenator >  xHyph, sal_Int16 nLang)
{
    LangCheckState_map_t &rLCS = GetLangCheckState();

    LangCheckState_map_t::iterator aIt( rLCS.find( nLang ) );
    sal_uInt16 nVal = aIt == rLCS.end() ? 0 : aIt->second;

    if (aIt == rLCS.end())
        rLCS[ nLang ] = nVal;

	if (SVX_LANG_NEED_CHECK == ((nVal >> 8) & 0x00FF))
	{
		sal_uInt16 nTmpVal = SVX_LANG_MISSING_DO_WARN;
		if (xHyph.is()  &&  xHyph->hasLocale( SvxCreateLocale( nLang ) ))
			nTmpVal = SVX_LANG_OK;
		nVal &= 0x00FF;
		nVal |= nTmpVal << 8;

        rLCS[ nLang ] = nVal;
	}

    return (sal_Int16) nVal;
}

// -----------------------------------------------------------------------


void SvxSpellWrapper::SpellStart( SvxSpellArea /*eSpell*/ )
{	// Hier muessen die notwendigen Vorbereitungen fuer SpellContinue
}	// im uebergebenen Bereich getroffen werden.

// -----------------------------------------------------------------------


sal_Bool SvxSpellWrapper::HasOtherCnt()
{
	return sal_False; // Gibt es ueberhaupt einen Sonderbereich?
}

// -----------------------------------------------------------------------


sal_Bool SvxSpellWrapper::SpellMore()
{
	return sal_False; // Sollen weitere Dokumente geprueft werden?
}

// -----------------------------------------------------------------------


void SvxSpellWrapper::SpellEnd()
{	// Bereich ist abgeschlossen, ggf. Aufraeumen

    // display error for last language not found
    ShowLanguageErrors();
}

// -----------------------------------------------------------------------


sal_Bool SvxSpellWrapper::SpellContinue()
{
	return sal_False;
}

// -----------------------------------------------------------------------

void SvxSpellWrapper::AutoCorrect( const String&, const String& )
{
}

// -----------------------------------------------------------------------


void SvxSpellWrapper::ScrollArea()
{	// Scrollarea einstellen
}

// -----------------------------------------------------------------------


void SvxSpellWrapper::ChangeWord( const String&, const sal_uInt16 )
{	// Wort ersetzen
}

// -----------------------------------------------------------------------


String SvxSpellWrapper::GetThesWord()
{
	// Welches Wort soll nachgeschlagen werden?
	return String();
}

// -----------------------------------------------------------------------


void SvxSpellWrapper::ChangeThesWord( const String& )
{
	// Wort wg. Thesaurus ersetzen
}

// -----------------------------------------------------------------------

void SvxSpellWrapper::StartThesaurus( const String &rWord, sal_uInt16 nLanguage )
{
	Reference< XThesaurus >  xThes( SvxGetThesaurus() );
	if (!xThes.is())
	{
		InfoBox( pWin, EE_RESSTR( RID_SVXSTR_HMERR_THESAURUS ) ).Execute();
		return;
	}

	WAIT_ON();	// while looking up for initial word
	EditAbstractDialogFactory* pFact = EditAbstractDialogFactory::Create();
	AbstractThesaurusDialog* pDlg = pFact->CreateThesaurusDialog( pWin, xThes, rWord, nLanguage );
	WAIT_OFF();
	if ( pDlg->Execute()== RET_OK )
	{
		ChangeThesWord( pDlg->GetWord() );
	}
	delete pDlg;
}

// -----------------------------------------------------------------------

void SvxSpellWrapper::ReplaceAll( const String &, sal_Int16 )
{	// Wort aus der Replace-Liste ersetzen
}

// -----------------------------------------------------------------------


void SvxSpellWrapper::SetLanguage( const sal_uInt16 )
{	// Sprache aendern
}

// -----------------------------------------------------------------------


void SvxSpellWrapper::InsertHyphen( const sal_uInt16 )
{	// Hyphen einfuegen bzw. loeschen
}

// -----------------------------------------------------------------------
// Pruefung der Dokumentbereiche in der durch die Flags angegebenen Reihenfolge


void SvxSpellWrapper::SpellDocument( )
{
	if ( bOtherCntnt )
	{
		bReverse = sal_False;
		SpellStart( SVX_SPELL_OTHER );
	}
	else
	{
		bStartChk = bReverse;
		SpellStart( bReverse ? SVX_SPELL_BODY_START : SVX_SPELL_BODY_END );
	}

	if ( FindSpellError() )
	{
		Reference< XSpellAlternatives >  	xAlt( GetLast(), UNO_QUERY );
		Reference< XHyphenatedWord > 		xHyphWord( GetLast(), UNO_QUERY );

		Window *pOld = pWin;
		bDialog = sal_True;
		if (xHyphWord.is())
		{
			EditAbstractDialogFactory* pFact = EditAbstractDialogFactory::Create();
			AbstractHyphenWordDialog* pDlg = pFact->CreateHyphenWordDialog( pWin,
							xHyphWord->getWord(),
							SvxLocaleToLanguage( xHyphWord->getLocale() ),
							xHyph, this );
			pWin = pDlg->GetWindow();
			pDlg->Execute();
			delete pDlg;
		}
		bDialog = sal_False;
		pWin = pOld;
	};
}

// -----------------------------------------------------------------------
// Naechsten Bereich auswaehlen


sal_Bool SvxSpellWrapper::SpellNext( )
{
	Reference< beans::XPropertySet >  xProp( SvxGetLinguPropertySet() );
	sal_Bool bWrapReverse = xProp.is() ?
			*(sal_Bool*)xProp->getPropertyValue(
				::rtl::OUString::createFromAscii(UPN_IS_WRAP_REVERSE) ).getValue()
			: sal_False;
	sal_Bool bActRev = bRevAllowed && bWrapReverse;

	// bActRev ist die Richtung nach dem Spellen, bReverse die am Anfang.
	if( bActRev == bReverse )
	{   						// Keine Richtungsaenderung, also ist
		if( bStartChk )         // der gewuenschte Bereich ( bStartChk )
			bStartDone = sal_True;  // vollstaendig abgearbeitet.
		else
			bEndDone = sal_True;
	}
	else if( bReverse == bStartChk ) // Bei einer Richtungsaenderung kann
	{ 						   // u.U. auch ein Bereich abgearbeitet sein.
		if( bStartChk )        // Sollte der vordere Teil rueckwaerts gespellt
			bEndDone = sal_True;   // werden und wir kehren unterwegs um, so ist
		else				   // der hintere Teil abgearbeitet (und umgekehrt).
			bStartDone = sal_True;
	}

	bReverse = bActRev;
	if( bOtherCntnt && bStartDone && bEndDone ) // Dokument komplett geprueft?
	{
		if ( SpellMore() )  // ein weiteres Dokument pruefen?
		{
			bOtherCntnt = sal_False;
			bStartDone = !bReverse;
			bEndDone  = bReverse;
			SpellStart( SVX_SPELL_BODY );
			return sal_True;
		}
		return sal_False;
	}

	sal_Bool bGoOn = sal_False;

	if ( bOtherCntnt )
	{
		bStartChk = sal_False;
		SpellStart( SVX_SPELL_BODY );
		bGoOn = sal_True;
	}
	else if ( bStartDone && bEndDone )
	{
		sal_Bool bIsSpellSpecial = xProp.is() ?
			*(sal_Bool*)xProp->getPropertyValue(
				::rtl::OUString::createFromAscii(UPN_IS_SPELL_SPECIAL) ).getValue()
			: sal_False;
		// Bodybereich erledigt, Frage nach Sonderbereich
		if( !IsHyphen() && bIsSpellSpecial && HasOtherCnt() )
		{
			SpellStart( SVX_SPELL_OTHER );
			bOtherCntnt = bGoOn = sal_True;
		}
		else if ( SpellMore() )  // ein weiteres Dokument pruefen?
		{
			bOtherCntnt = sal_False;
			bStartDone = !bReverse;
			bEndDone  = bReverse;
			SpellStart( SVX_SPELL_BODY );
			return sal_True;
		}
	}
	else
	{
		// Ein BODY_Bereich erledigt, Frage nach dem anderen BODY_Bereich
		WAIT_OFF();

// Sobald im Dialog das DontWrapAround gesetzt werden kann, kann der
// folgende #ifdef-Zweig aktiviert werden ...
#ifdef USED
		sal_Bool bDontWrapAround = IsHyphen() ?
			pSpell->GetOptions() & DONT_WRAPAROUND :
			pSpell->GetHyphOptions() & HYPH_DONT_WRAPAROUND;
		if( bDontWrapAround )
#else
		sal_uInt16 nResId = bReverse ? RID_SVXQB_BW_CONTINUE : RID_SVXQB_CONTINUE;
		QueryBox aBox( pWin, EditResId( nResId ) );
		if ( aBox.Execute() != RET_YES )
#endif

		{
			// Verzicht auf den anderen Bereich, ggf. Frage nach Sonderbereich
			WAIT_ON();
			bStartDone = bEndDone = sal_True;
			return SpellNext();
		}
		else
		{
			bStartChk = !bStartDone;
			SpellStart( bStartChk ? SVX_SPELL_BODY_START : SVX_SPELL_BODY_END );
			bGoOn = sal_True;
		}
		WAIT_ON();
	}
	return bGoOn;
}

// -----------------------------------------------------------------------

Reference< XDictionary >  SvxSpellWrapper::GetAllRightDic() const
{
    Reference< XDictionary >  xDic;

	Reference< XDictionaryList >  xDicList( SvxGetDictionaryList() );
	if (xDicList.is())
	{
		Sequence< Reference< XDictionary >  > aDics( xDicList->getDictionaries() );
		const Reference< XDictionary >  *pDic = aDics.getConstArray();
		sal_Int32 nCount = aDics.getLength();

		sal_Int32 i = 0;
		while (!xDic.is()  &&  i < nCount)
		{
            Reference< XDictionary >  xTmp( pDic[i], UNO_QUERY );
			if (xTmp.is())
			{
				if ( xTmp->isActive() &&
					 xTmp->getDictionaryType() != DictionaryType_NEGATIVE &&
                     SvxLocaleToLanguage( xTmp->getLocale() ) == LANGUAGE_NONE )
				{
					Reference< frame::XStorable >  xStor( xTmp, UNO_QUERY );
					if (xStor.is() && xStor->hasLocation() && !xStor->isReadonly())
					{
						xDic = xTmp;
					}
				}
			}
			++i;
		}

		if (!xDic.is())
		{
			xDic = SvxGetOrCreatePosDic( xDicList );
			if (xDic.is())
				xDic->setActive( sal_True );
		}
	}

	return xDic;
}

// -----------------------------------------------------------------------

sal_Bool SvxSpellWrapper::FindSpellError()
{
    ShowLanguageErrors();

 	Reference< XInterface > 	xRef;

	WAIT_ON();
	sal_Bool bSpell = sal_True;

    Reference< XDictionary >  xAllRightDic;
	if (IsAllRight())
		xAllRightDic = GetAllRightDic();

	while ( bSpell )
	{
		SpellContinue();

		Reference< XSpellAlternatives >  	xAlt( GetLast(), UNO_QUERY );
		Reference< XHyphenatedWord > 		xHyphWord( GetLast(), UNO_QUERY );

		if (xAlt.is())
		{
			if (IsAllRight() && xAllRightDic.is())
			{
				xAllRightDic->add( xAlt->getWord(), sal_False, ::rtl::OUString() );
			}
			else
			{
				// look up in ChangeAllList for misspelled word
                Reference< XDictionary >    xChangeAllList(
						SvxGetChangeAllList(), UNO_QUERY );
				Reference< XDictionaryEntry > 	xEntry;
				if (xChangeAllList.is())
					xEntry = xChangeAllList->getEntry( xAlt->getWord() );

				if (xEntry.is())
				{
					// replace word without asking
					ReplaceAll( xEntry->getReplacementText(),
								SvxLocaleToLanguage( xAlt->getLocale() ) );
				}
				else
					bSpell = sal_False;
			}
		}
		else if (xHyphWord.is())
			bSpell = sal_False;
		else
		{
			SpellEnd();
			bSpell = SpellNext();
		}
	}
	WAIT_OFF();
	return GetLast().is();
}
