/***************************************************************************
 *   Copyright (C) 2006 by Tobias Koenig <tokoe@kde.org>                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

#include "formatproperty.h"

#include <QTextFormat>

#include "styleinformation.h"

using namespace OOO;

FontFormatProperty::FontFormatProperty()
  : mFamily( QStringLiteral("Nimbus Sans L") )
{
}

void FontFormatProperty::apply( QTextFormat *format ) const
{
  format->setProperty( QTextFormat::FontFamily, mFamily );
}


void FontFormatProperty::setFamily( const QString &name )
{
  mFamily = name;
}

ParagraphFormatProperty::ParagraphFormatProperty()
  : mPageNumber( 0 ), mWritingMode( LRTB ), mAlignment( Qt::AlignLeft ),
    mHasAlignment( false )
{
}

void ParagraphFormatProperty::apply( QTextFormat *format ) const
{
  if ( mWritingMode == LRTB || mWritingMode == TBLR || mWritingMode == LR || mWritingMode == TB )
    format->setLayoutDirection( Qt::LeftToRight );
  else
    format->setLayoutDirection( Qt::RightToLeft );

  if ( mHasAlignment ) {
    static_cast<QTextBlockFormat*>( format )->setAlignment( mAlignment );
  }

  format->setProperty( QTextFormat::FrameWidth, 595 );

  static_cast<QTextBlockFormat*>( format )->setLeftMargin( mLeftMargin );

  if ( mBackgroundColor.isValid() )
    format->setBackground( mBackgroundColor );
}

void ParagraphFormatProperty::setPageNumber( int number )
{
  mPageNumber = number;
}

void ParagraphFormatProperty::setWritingMode( WritingMode mode )
{
  mWritingMode = mode;
}

bool ParagraphFormatProperty::writingModeIsRightToLeft() const
{
  return ( ( mWritingMode == RLTB ) || ( mWritingMode == TBRL ) || ( mWritingMode == RL ) );
}

void ParagraphFormatProperty::setTextAlignment( Qt::Alignment alignment )
{
  mHasAlignment = true;
  mAlignment = alignment;
}

void ParagraphFormatProperty::setBackgroundColor( const QColor &color )
{
  mBackgroundColor = color;
}

void ParagraphFormatProperty::setLeftMargin( const qreal margin )
{
  mLeftMargin = margin;
}

TextFormatProperty::TextFormatProperty()
  : mStyleInformation( nullptr ), mHasFontSize( false ),
    mFontWeight( -1 ), mFontStyle( -1 ), mTextPosition( 0 )
{
}

TextFormatProperty::TextFormatProperty( const StyleInformation *information )
  : mStyleInformation( information ), mHasFontSize( false ),
    mFontWeight( -1 ), mFontStyle( -1 ), mTextPosition( 0 )
{
}

void TextFormatProperty::apply( QTextCharFormat *format ) const
{
  if ( !mFontName.isEmpty() ) {
    if ( mStyleInformation ) {
      const FontFormatProperty property = mStyleInformation->fontProperty( mFontName );
      property.apply( format );
    }
  }

  if ( mFontWeight != -1 ) {
    QFont font = format->font();
    font.setWeight( mFontWeight );
    format->setFont( font );
  }

  if ( mHasFontSize ) {
    QFont font = format->font();
    font.setPointSize( mFontSize );
    format->setFont( font );
  }

  if ( mFontStyle != -1 ) {
    QFont font = format->font();
    font.setStyle( (QFont::Style)mFontStyle );
    format->setFont( font );
  }

  if ( mColor.isValid() )
    format->setForeground( mColor );

  if ( mBackgroundColor.isValid() )
    format->setBackground( mBackgroundColor );

  // TODO: get FontFormatProperty and apply it
  // TODO: how to set the base line?!?
}

void TextFormatProperty::setFontSize( int size )
{
  mHasFontSize = true;
  mFontSize = size;
}

void TextFormatProperty::setFontName( const QString &name )
{
  mFontName = name;
}

void TextFormatProperty::setFontWeight( int weight )
{
  mFontWeight = weight;
}

void TextFormatProperty::setFontStyle( int style )
{
  mFontStyle = style;
}

void TextFormatProperty::setTextPosition( int position )
{
  mTextPosition = position;
}

void TextFormatProperty::setColor( const QColor &color )
{
  mColor = color;
}

void TextFormatProperty::setBackgroundColor( const QColor &color )
{
  mBackgroundColor = color;
}

StyleFormatProperty::StyleFormatProperty()
  : mStyleInformation( nullptr ), mDefaultStyle( false )
{
}

StyleFormatProperty::StyleFormatProperty( const StyleInformation *information )
  : mStyleInformation( information ), mDefaultStyle( false )
{
}

void StyleFormatProperty::applyBlock( QTextBlockFormat *format ) const
{
  if ( !mDefaultStyle && !mFamily.isEmpty() && mStyleInformation ) {
    const StyleFormatProperty property = mStyleInformation->styleProperty( mFamily );
    property.applyBlock( format );
  }

  if ( !mParentStyleName.isEmpty() && mStyleInformation ) {
    const StyleFormatProperty property = mStyleInformation->styleProperty( mParentStyleName );
    property.applyBlock( format );
  }

  mParagraphFormat.apply( format );
}

void StyleFormatProperty::applyText( QTextCharFormat *format ) const
{
  if ( !mDefaultStyle && !mFamily.isEmpty() && mStyleInformation ) {
    const StyleFormatProperty property = mStyleInformation->styleProperty( mFamily );
    property.applyText( format );
  }

  if ( !mParentStyleName.isEmpty() && mStyleInformation ) {
    const StyleFormatProperty property = mStyleInformation->styleProperty( mParentStyleName );
    property.applyText( format );
  }

  mTextFormat.apply( format );
}

void StyleFormatProperty::applyTableColumn( QTextTableFormat *format ) const
{
  if ( !mDefaultStyle && !mFamily.isEmpty() && mStyleInformation ) {
    const StyleFormatProperty property = mStyleInformation->styleProperty( mFamily );
    property.applyTableColumn( format );
  }

  if ( !mParentStyleName.isEmpty() && mStyleInformation ) {
    const StyleFormatProperty property = mStyleInformation->styleProperty( mParentStyleName );
    property.applyTableColumn( format );
  }

  mTableColumnFormat.apply( format );
}

void StyleFormatProperty::applyTableCell( QTextBlockFormat *format ) const
{
  if ( !mDefaultStyle && !mFamily.isEmpty() && mStyleInformation ) {
    const StyleFormatProperty property = mStyleInformation->styleProperty( mFamily );
    property.applyTableCell( format );
  }

  if ( !mParentStyleName.isEmpty() && mStyleInformation ) {
    const StyleFormatProperty property = mStyleInformation->styleProperty( mParentStyleName );
    property.applyTableCell( format );
  }

  mTableCellFormat.apply( format );
}

void StyleFormatProperty::setParentStyleName( const QString &parentStyleName )
{
  mParentStyleName = parentStyleName;
}

QString StyleFormatProperty::parentStyleName() const
{
  return mParentStyleName;
}

void StyleFormatProperty::setFamily( const QString &family )
{
  mFamily = family;
}

void StyleFormatProperty::setDefaultStyle( bool defaultStyle )
{
  mDefaultStyle = defaultStyle;
}

void StyleFormatProperty::setMasterPageName( const QString &masterPageName )
{
  mMasterPageName = masterPageName;
}

void StyleFormatProperty::setParagraphFormat( const ParagraphFormatProperty &format )
{
  mParagraphFormat = format;
}

void StyleFormatProperty::setTextFormat( const TextFormatProperty &format )
{
  mTextFormat = format;
}

void StyleFormatProperty::setTableColumnFormat( const TableColumnFormatProperty format )
{
  mTableColumnFormat = format;
}

void StyleFormatProperty::setTableCellFormat( const TableCellFormatProperty &format )
{
  mTableCellFormat = format;
}

PageFormatProperty::PageFormatProperty()
  : mHeight( 0.0 ), mWidth( 0.0 )
{
}

void PageFormatProperty::apply( QTextFormat *format ) const
{
  format->setProperty( QTextFormat::BlockBottomMargin, mBottomMargin );
  format->setProperty( QTextFormat::BlockLeftMargin, mLeftMargin );
  format->setProperty( QTextFormat::BlockTopMargin, mTopMargin );
  format->setProperty( QTextFormat::BlockRightMargin, mRightMargin );
  format->setProperty( QTextFormat::FrameWidth, mWidth );
  format->setProperty( QTextFormat::FrameHeight, mHeight );
}

void PageFormatProperty::setPageUsage( PageUsage usage )
{
  mPageUsage = usage;
}

void PageFormatProperty::setBottomMargin( double margin )
{
  mBottomMargin = margin;
}

void PageFormatProperty::setLeftMargin( double margin )
{
  mLeftMargin = margin;
}

void PageFormatProperty::setTopMargin( double margin )
{
  mTopMargin = margin;
}

void PageFormatProperty::setRightMargin( double margin )
{
  mRightMargin = margin;
}

void PageFormatProperty::setHeight( double height )
{
  mHeight = height;
}

void PageFormatProperty::setWidth( double width )
{
  mWidth = width;
}

void PageFormatProperty::setPrintOrientation( PrintOrientation orientation )
{
  mPrintOrientation = orientation;
}

double PageFormatProperty::width() const
{
  return mWidth;
}

double PageFormatProperty::height() const
{
  return mHeight;
}

double PageFormatProperty::margin() const
{
  return mLeftMargin;
}

ListFormatProperty::ListFormatProperty()
  : mType( Number )
{
  mIndents.resize( 10 );
}

ListFormatProperty::ListFormatProperty( Type type )
  : mType( type )
{
  mIndents.resize( 10 );
}

void ListFormatProperty::apply( QTextListFormat *format, int level ) const
{
  if ( mType == Number )
    format->setStyle( QTextListFormat::ListDecimal );
  else {
    format->setStyle( QTextListFormat::ListDisc );
    if ( level > 0 && level < 10 )
      format->setIndent( qRound( mIndents[ level ] ) );
  }
}

void ListFormatProperty::addItem( int level, double indent )
{
  if ( level < 0 || level >= 10 )
    return;

  mIndents[ level ] = indent;
}

TableColumnFormatProperty::TableColumnFormatProperty()
  : mWidth( 0 ), isValid( false )
{
}

void TableColumnFormatProperty::apply( QTextTableFormat *format ) const
{
  if ( ! isValid ) {
    return;
  }
  QVector<QTextLength> lengths = format->columnWidthConstraints();
  lengths.append( QTextLength( QTextLength::FixedLength, mWidth ) );

  format->setColumnWidthConstraints( lengths );
}

void TableColumnFormatProperty::setWidth( double width )
{
  mWidth = width;
  isValid = true;
}

TableCellFormatProperty::TableCellFormatProperty()
  : mPadding( 0 ), mHasAlignment( false )
{
}

void TableCellFormatProperty::apply( QTextBlockFormat *format ) const
{
  if ( mBackgroundColor.isValid() )
    format->setBackground( mBackgroundColor );

  if ( mHasAlignment )
    format->setAlignment( mAlignment );
}

void TableCellFormatProperty::setBackgroundColor( const QColor &color )
{
  mBackgroundColor = color;
}

void TableCellFormatProperty::setPadding( double padding )
{
  mPadding = padding;
}

void TableCellFormatProperty::setAlignment( Qt::Alignment alignment )
{
  mAlignment = alignment;
  mHasAlignment = true;
}
