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

#include <comphelper/processfactory.hxx>
#include <dialmgr.hxx>
#include <osl/file.hxx>
#include <rtl/bootstrap.hxx>
//#include <rtl/ustrbuf.hxx>
#include <sfx2/sfxcommands.h>
#include <sfx2/sfxdefs.hxx>
#include <sfx2/sfxuno.hxx>
#include <svtools/filter.hxx>
#include <svtools/svtools.hrc>
#include <tools/stream.hxx>
#include <tools/urlobj.hxx>
#include <unotools/bootstrap.hxx>
#include <unotools/configmgr.hxx>
#include <vcl/graph.hxx>
#include <vcl/imagerepository.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/svapp.hxx>
#include <vcl/tabctrl.hxx>
#include <vcl/tabdlg.hxx>
#include <vcl/tabpage.hxx>

#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
#include <com/sun/star/system/SystemShellExecute.hpp>
#include <com/sun/star/uno/Any.h>

#include "about.hxx"
#include "about.hrc"

#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)

/* On Windows/OS2, all the three files have .txt extension
   and the README file name is in lowercase
   Readme files are localized and have the locale in their file name:
   README_de README_en-US
*/
#if defined(WNT) || defined(OS2)
#define FILE_EXTENSION  ".txt"
#define README_FILE     "readme"
#else
#define FILE_EXTENSION
#define README_FILE     "README"
#endif
#define LICENSE_FILE    "LICENSE" FILE_EXTENSION
#define NOTICE_FILE     "NOTICE"  FILE_EXTENSION

// Dir where the files are located
#define OOO_DIR_SHARE_README  "${OOO_BASE_DIR}/share/readme/"

using namespace com::sun::star;

namespace
{

    static void lcl_layoutFixedText( FixedText &rControl,
                                     const Point& aPos,
                                     Size &aSize,
                                     const long nTextWidth )
    {
        aSize = rControl.GetSizePixel();
        // change the width
        aSize.Width() = nTextWidth;
        // set Position and Size, to calculate the minimum size
        // this will update the Height
        rControl.SetPosSizePixel( aPos, aSize );
        aSize = rControl.CalcMinimumSize();
        // update the size with the right Height
        rControl.SetSizePixel( aSize );
    }

    static void lcl_layoutEdit( Edit &rControl,
                                const Point& aPos,
                                Size &aSize,
                                const long nTextWidth )
    {
        aSize = rControl.GetSizePixel();
        // change the width
        aSize.Width() = nTextWidth;
        // set Position and Size, to calculate the minimum size
        // this will update the Height
        rControl.SetPosSizePixel( aPos, aSize );
        aSize = rControl.CalcMinimumSize();
        // update the size with the right Height
        rControl.SetSizePixel( aSize );
    }

    static  void lcl_readTxtFile( const rtl::OUString &rFile, rtl::OUString &sText )
    {
        rtl::OUString sFile( rFile );
        rtl::Bootstrap::expandMacros( sFile );
        osl::File aFile(sFile);
        if ( aFile.open(OpenFlag_Read) == osl::FileBase::E_None )
        {
            osl::DirectoryItem aItem;
            osl::DirectoryItem::get(sFile, aItem);

            osl::FileStatus aStatus(FileStatusMask_FileSize);
            aItem.getFileStatus(aStatus);

            sal_uInt64 nBytesRead = 0;
            sal_uInt64 nPosition = 0;
            sal_uInt32 nBytes = (sal_uInt32)aStatus.getFileSize();

            sal_Char *pBuffer = new sal_Char[nBytes];

            while ( aFile.read( pBuffer + nPosition,
                                nBytes-nPosition,
                                nBytesRead ) == osl::FileBase::E_None
                    && nPosition + nBytesRead < nBytes)
            {
                nPosition += nBytesRead;
            }

            OSL_ENSURE( nBytes < STRING_MAXLEN, "Text file has too much bytes!" );
            if ( nBytes > STRING_MAXLEN )
                nBytes = STRING_MAXLEN - 1;

            sText = rtl::OUString( pBuffer,
                                nBytes,
                                RTL_TEXTENCODING_UTF8,
                                OSTRING_TO_OUSTRING_CVTFLAGS
                                | RTL_TEXTTOUNICODE_FLAGS_GLOBAL_SIGNATURE);
            delete[] pBuffer;
        }
    }

    class ReadmeDialog;

    class ReadmeTabPage : public TabPage
    {
    private:
        MultiLineEdit maText;
        String        msText;

    public:
        ReadmeTabPage(Window *pParent, const String &sText);
        ~ReadmeTabPage();

        void Adjust(const Size &aSz, const Size &a6Size);
    };

    ReadmeTabPage::ReadmeTabPage(Window *pParent, const String &sText)
        : TabPage(pParent, CUI_RES( RID_CUI_README_TBPAGE))
        ,maText( this, CUI_RES( RID_CUI_README_TBPAGE_EDIT ))
        ,msText( sText )
    {
        FreeResource();

        maText.SetText(msText);
        maText.Show();
    }

    ReadmeTabPage::~ReadmeTabPage()
    {
    }

    void ReadmeTabPage::Adjust(const Size &aSz, const Size &a6Size)
    {
        long nDlgMargin  = a6Size.Width() * 2;
        long nCtrlMargin = a6Size.Height() * 2;
        maText.SetPosPixel( Point(a6Size.Width(), a6Size.Height()) );
        maText.SetSizePixel( Size(aSz.Width() - nDlgMargin, aSz.Height() - nCtrlMargin) );
    }

    class ReadmeDialog : public ModalDialog
    {
    private:
        TabControl      maTabCtrl;
        OKButton        maBtnOK;

        ReadmeTabPage  *maReadmeTabPage;
        ReadmeTabPage  *maLicenseTabPage;
        ReadmeTabPage  *maNoticeTabPage;

        DECL_LINK( ActivatePageHdl, TabControl * );
        DECL_LINK( DeactivatePageHdl, TabControl * );

    public:
        ReadmeDialog( Window* );
        ~ReadmeDialog();
    };

    ReadmeDialog::ReadmeDialog( Window * pParent )
        : ModalDialog( pParent, CUI_RES( RID_CUI_README_DLG ) )
        , maTabCtrl( this, CUI_RES(RID_CUI_README_TBCTL) )
        , maBtnOK( this, CUI_RES(RID_CUI_README_OKBTN) )
        , maReadmeTabPage(0)
        , maLicenseTabPage(0)
        , maNoticeTabPage(0)
    {
        FreeResource();

        maTabCtrl.Show();

        // Notice and License are not localized
        const rtl::OUString sLicense( RTL_CONSTASCII_USTRINGPARAM( OOO_DIR_SHARE_README LICENSE_FILE ) );
        const rtl::OUString sNotice( RTL_CONSTASCII_USTRINGPARAM(  OOO_DIR_SHARE_README NOTICE_FILE ) );

        // get localized README
        rtl::OUStringBuffer aBuff;
        lang::Locale aLocale = Application::GetSettings().GetUILocale();
        aBuff.appendAscii( RTL_CONSTASCII_STRINGPARAM( OOO_DIR_SHARE_README README_FILE "_" ) );
        aBuff.append( aLocale.Language );
        if ( aLocale.Country.getLength() )
        {
            aBuff.append( sal_Unicode( '-') );
            aBuff.append( aLocale.Country );
            if ( aLocale.Variant.getLength() )
            {
                aBuff.append( sal_Unicode( '-' ) );
                aBuff.append( aLocale.Variant );
            }
        }
#if defined(WNT) || defined(OS2)
        aBuff.appendAscii( RTL_CONSTASCII_STRINGPARAM( FILE_EXTENSION ) );
#endif

        rtl::OUString sReadmeTxt, sLicenseTxt, sNoticeTxt;
        lcl_readTxtFile( aBuff.makeStringAndClear(), sReadmeTxt );
        lcl_readTxtFile( sLicense, sLicenseTxt );
        lcl_readTxtFile( sNotice, sNoticeTxt );

        maReadmeTabPage = new ReadmeTabPage( &maTabCtrl, sReadmeTxt );
        maLicenseTabPage = new ReadmeTabPage( &maTabCtrl, sLicenseTxt );
        maNoticeTabPage = new ReadmeTabPage( &maTabCtrl, sNoticeTxt );

        maTabCtrl.SetTabPage( RID_CUI_READMEPAGE, maReadmeTabPage );
        maTabCtrl.SetTabPage( RID_CUI_LICENSEPAGE, maLicenseTabPage );
        maTabCtrl.SetTabPage( RID_CUI_NOTICEPAGE, maNoticeTabPage );

        maTabCtrl.SelectTabPage( RID_CUI_READMEPAGE );

        Size aTpSz  = maReadmeTabPage->GetOutputSizePixel();
        Size a6Size = maReadmeTabPage->LogicToPixel( Size( 6, 6 ), MAP_APPFONT );

        maReadmeTabPage->Adjust( aTpSz, a6Size );
        maLicenseTabPage->Adjust( aTpSz, a6Size );
        maNoticeTabPage->Adjust( aTpSz, a6Size );

        Size aDlgSize = GetOutputSizePixel();
        Size aOkBtnSz = maBtnOK.GetSizePixel();
        Point aOKPnt( aDlgSize.Width() / 2 - aOkBtnSz.Width() / 2 , maBtnOK.GetPosPixel().Y() );
        maBtnOK.SetPosPixel( aOKPnt );
    }

    ReadmeDialog::~ReadmeDialog()
    {
        delete maReadmeTabPage;
        delete maLicenseTabPage;
        delete maNoticeTabPage;
    }
}

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

AboutDialog::AboutDialog( Window* pParent, const ResId  & rId ) :
    SfxModalDialog( pParent, rId ),
    maOKButton( this, ResId( RID_CUI_ABOUT_BTN_OK, *rId.GetResMgr() ) ),
    maReadmeButton( this, ResId( RID_CUI_ABOUT_BTN_README, *rId.GetResMgr() ) ),
    maVersionText( this, ResId( RID_CUI_ABOUT_FTXT_VERSION, *rId.GetResMgr() ) ),
    maBuildInfoEdit( this, ResId( RID_CUI_ABOUT_FTXT_BUILDDATA, *rId.GetResMgr() ) ),
    maCopyrightEdit( this, ResId( RID_CUI_ABOUT_FTXT_COPYRIGHT, *rId.GetResMgr() ) ),
    maCreditsLink( this, ResId( RID_CUI_ABOUT_FTXT_WELCOME_LINK, *rId.GetResMgr() )  )
//    maCopyrightTextStr( ResId( RID_CUI_ABOUT_STR_COPYRIGHT, *rId.GetResMgr() ) )
{
    bool bLoad = vcl::ImageRepository::loadBrandingImage(
            rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("about")),
            maAppLogo );
    OSL_ENSURE( bLoad, "Can't load about image");

    bLoad = vcl::ImageRepository::loadBrandingImage(
            rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("logo")),
            maMainLogo );
    OSL_ENSURE( bLoad, "Can't load logo image");

    const String vendor( ResId( RID_CUI_ABOUT_STR_COPYRIGHT_VENDOR, *rId.GetResMgr() ) );  
    String createdRes( ResId( RID_CUI_ABOUT_STR_CREATED, *rId.GetResMgr() ) );  
    if ( !vendor.EqualsAscii("Apache Software Foundation") ) {
        createdRes = String( ResId( RID_CUI_ABOUT_STR_CREATED_VENDOR, *rId.GetResMgr() ));
    }
    const String copyrightAcknowledge( ResId( RID_CUI_ABOUT_STR_ACKNOWLEDGE, *rId.GetResMgr() ) );  
    
    rtl::OUStringBuffer sbcopyright(250);
    sbcopyright.appendAscii("Copyright ");
    sbcopyright.append((sal_Unicode)0x00a9);
    sbcopyright.appendAscii(" ");
    rtl::OUString sYear( RTL_CONSTASCII_USTRINGPARAM("2015") );
    if (vendor.EqualsAscii("Apache Software Foundation")) {
        sbcopyright.append(sYear);
        sbcopyright.appendAscii(" The Apache Software Foundation.\n\n");
    } else {
#ifdef COPYRIGHT_YEAR
        const rtl::OUString sDefYear( RTL_CONSTASCII_USTRINGPARAM( STRINGIFY( COPYRIGHT_YEAR ) ) );
        if ( sDefYear.getLength() > 0 )
        {
            sYear = sDefYear;
        } 
#endif
        sbcopyright.append(sYear);
        sbcopyright.appendAscii(" ");
        sbcopyright.append(vendor);
        sbcopyright.appendAscii(".\nPortion copyright The Apache Software Foundation.\n\n");
    }
    sbcopyright.append( createdRes );
    sbcopyright.appendAscii("\n\n");
    sbcopyright.append( copyrightAcknowledge );
    maCopyrightTextStr = sbcopyright.makeStringAndClear();
    
    InitControls();

    // set links
    maReadmeButton.SetClickHdl( LINK( this, AboutDialog, ShowReadme_Impl ) );
    maCreditsLink.SetClickHdl( LINK( this, AboutDialog, OpenLinkHdl_Impl ) );

    FreeResource();

    SetHelpId( CMD_SID_ABOUT );
}

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

AboutDialog::~AboutDialog()
{
}

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

void AboutDialog::InitControls()
{
    // apply font, background et al.
    ApplyStyleSettings();

    // set strings
    maCopyrightEdit.SetText( maCopyrightTextStr );
    maBuildInfoEdit.SetText( GetBuildVersionString() );
    maCreditsLink.SetURL( maCreditsLink.GetText() );

    // determine size and position of the dialog & elements
    Size aDlgSize;
    LayoutControls( aDlgSize );

    // Change the width of the dialog
    SetOutputSizePixel( aDlgSize );
}

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

void AboutDialog::ApplyStyleSettings()
{
    // Transparenter Font
    Font aFont = GetFont();
    aFont.SetTransparent( sal_True );
    SetFont( aFont );

    // set for background and text the correct system color
    const StyleSettings& rSettings = GetSettings().GetStyleSettings();
    Color aWindowColor( rSettings.GetWindowColor() );
    Wallpaper aWall( aWindowColor );
    SetBackground( aWall );

    Font aNewFont( maCopyrightEdit.GetFont() );
    aNewFont.SetTransparent( sal_True );

    maVersionText.SetFont( aNewFont );
    maCopyrightEdit.SetFont( aNewFont );

    maVersionText.SetBackground(aWall);
    maCopyrightEdit.SetBackground(aWall);
    maBuildInfoEdit.SetBackground(aWall);
    maCreditsLink.SetBackground(aWall);

    Color aTextColor( rSettings.GetWindowTextColor() );
    maVersionText.SetControlForeground( aTextColor );
    maCopyrightEdit.SetControlForeground( aTextColor );
    maBuildInfoEdit.SetControlForeground( aTextColor );
    maCreditsLink.SetControlForeground();

    Size aSmaller = aNewFont.GetSize();
    aSmaller.Width() = (long) (aSmaller.Width() * 0.75);
    aSmaller.Height() = (long) (aSmaller.Height() * 0.75);
    aNewFont.SetSize( aSmaller );

    maBuildInfoEdit.SetFont( aNewFont );

    // the following is a hack to force the MultiLineEdit update its settings
    // in order to reflect the Font
    // See
    //      Window::SetControlFont
    //      MultiLineEdit::StateChanged
    //      MultiLineEdit::ImplInitSettings
    // TODO Override SetFont in MultiLineEdit and do the following,
    // otherwise SetFont has no effect at all!
    aSmaller = PixelToLogic( aSmaller, MAP_POINT );
    aNewFont.SetSize( aSmaller );
    maBuildInfoEdit.SetControlFont( aNewFont );
}

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

void AboutDialog::LayoutControls( Size& aDlgSize )
{
    Size aMainLogoSz = maMainLogo.GetSizePixel();
    Size aAppLogoSiz = maAppLogo.GetSizePixel();

    aDlgSize = GetOutputSizePixel();
    long nCol1 = aMainLogoSz.Width();
    long nCol2 = aAppLogoSiz.Width() ? aAppLogoSiz.Width() : aDlgSize.Width();

    Size a6Size      = maVersionText.LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
    long nDlgMargin  = a6Size.Width() * 2;
    long nCtrlMargin = a6Size.Height() * 2;
    long nTextWidth  = nCol2 - nDlgMargin;
    long nY          = aAppLogoSiz.Height() + a6Size.Height();

    aDlgSize.Width() = nCol1 + a6Size.Width() + nCol2;

    Point aPos( nCol1 + a6Size.Width(), nY );
    Size aSize;
    // layout fixed text control
    lcl_layoutFixedText( maVersionText, aPos, aSize, nTextWidth );
    nY += aSize.Height() + a6Size.Height();

    // Multiline edit with Build info
    aPos.Y() = nY;
    lcl_layoutEdit( maBuildInfoEdit, aPos, aSize, nTextWidth );
    nY += aSize.Height() + a6Size.Height();

    // Multiline edit with Copyright-Text
    aPos.Y() = nY;
    lcl_layoutEdit( maCopyrightEdit, aPos, aSize, nTextWidth );
    nY += aSize.Height() + a6Size.Height();

    // Hyperlink
    aPos.Y() = nY;
    lcl_layoutFixedText( maCreditsLink, aPos, aSize, nTextWidth );
    nY += aSize.Height();

    nY = std::max( nY, aMainLogoSz.Height() );
    nY += nCtrlMargin;

    // logos position
    maMainLogoPos = Point( 0, nY / 2 - aMainLogoSz.Height() / 2 );
    maAppLogoPos = Point( nCol1 + a6Size.Width(), 0 );

    // OK-Button-Position (at the bottom and centered)
    Size aOKSiz = maOKButton.GetSizePixel();
    Point aOKPnt( ( aDlgSize.Width() - aOKSiz.Width() ) - a6Size.Width(), nY );
    maOKButton.SetPosPixel( aOKPnt );

    maReadmeButton.SetPosPixel( Point(a6Size.Width(), nY) );

    aDlgSize.Height() = aOKPnt.Y() + aOKSiz.Height() + a6Size.Width();
}

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

const rtl::OUString AboutDialog::GetBuildId() const
{
    rtl::OUString sDefault;

    // Get buildid from version[rc|.ini]
    rtl::OUString sBuildId( utl::Bootstrap::getBuildIdData( sDefault ) );
    OSL_ENSURE( sBuildId.getLength() > 0, "No BUILDID in bootstrap file" );
    rtl::OUStringBuffer sBuildIdBuff( sBuildId );

    // Get ProductSource from version[rc|.ini]
    rtl::OUString sProductSource( utl::Bootstrap::getProductSource( sDefault ) );
    OSL_ENSURE( sProductSource.getLength() > 0, "No ProductSource in bootstrap file" );

    // the product source is something like "AOO340",
    // while the build id is something like "340m1(Build:9590)"
    // For better readability, strip the duplicate ProductMajor ("340").
    if ( sProductSource.getLength() )
    {
        bool bMatchingUPD =
                ( sProductSource.getLength() >= 3 )
            &&  ( sBuildId.getLength() >= 3 )
            &&  ( sProductSource.copy( sProductSource.getLength() - 3 ) == sBuildId.copy( 0, 3 ) );
        OSL_ENSURE( bMatchingUPD, "BUILDID and ProductSource do not match in their UPD" );
        if ( bMatchingUPD )
            sProductSource = sProductSource.copy( 0, sProductSource.getLength() - 3 );

        // prepend the product source
        sBuildIdBuff.insert( 0, sProductSource );
    }

    return sBuildIdBuff.makeStringAndClear();
}

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

const rtl::OUString AboutDialog::GetBuildVersionString() const
{
    rtl::OUStringBuffer aBuildString( GetBuildId() );
    rtl::OUString sRevision( utl::Bootstrap::getRevisionInfo() );

    if ( sRevision.getLength() > 0 )
    {
        aBuildString.appendAscii( RTL_CONSTASCII_STRINGPARAM( "  -  Rev. " ) );
        aBuildString.append( sRevision );
    }

#ifdef BUILD_VER_STRING
    rtl::OUString sBuildVer( RTL_CONSTASCII_USTRINGPARAM( STRINGIFY( BUILD_VER_STRING ) ) );
    if ( sBuildVer.getLength() > 0 )
    {
        aBuildString.append( sal_Unicode( '\n' ) );
        aBuildString.append( sBuildVer );
    }
#endif

    return aBuildString.makeStringAndClear();
}

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

sal_Bool AboutDialog::Close()
{
    EndDialog( RET_OK );
    return( sal_False );
}

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

void AboutDialog::Paint( const Rectangle& rRect )
{
    SetClipRegion( rRect );

    // workaround to ensure that the background is painted correct
    // on MacOS for example the background was grey and the image and other controls white
    SetFillColor(GetSettings().GetStyleSettings().GetWindowColor());
    SetLineColor();
    DrawRect(rRect);

    DrawImage( maMainLogoPos, maMainLogo );
    DrawImage( maAppLogoPos, maAppLogo );

    return;
}

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

IMPL_LINK ( AboutDialog, OpenLinkHdl_Impl, svt::FixedHyperlink*, EMPTYARG )
{
    ::rtl::OUString sURL( maCreditsLink.GetURL() );
    if ( sURL.getLength() > 0 )
    {
        try
        {
            uno::Reference< com::sun::star::system::XSystemShellExecute > xSystemShell(
                com::sun::star::system::SystemShellExecute::create(
                    ::comphelper::getProcessComponentContext() ) );
            if ( xSystemShell.is() )
                xSystemShell->execute( sURL, rtl::OUString(), com::sun::star::system::SystemShellExecuteFlags::DEFAULTS );
        }
        catch( const uno::Exception& e )
        {
             OSL_TRACE( "Caught exception: %s\n thread terminated.\n",
                rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
        }
    }

    return 0;
}

IMPL_LINK ( AboutDialog, ShowReadme_Impl, PushButton*, EMPTYARG )
{
    ReadmeDialog aDlg( this );
    aDlg.Execute();

    return 0;
}
