using System;
using System.Drawing;

// Creation date: 24.04.2002
// Checked: 20.08.2002
// Author: Otto Mayer (mot@root.ch)
// Version: 1.01

// Report.NET copyright 2002-2004 root-software ag, Bürglen Switzerland - O. Mayer, S. Spirig, R. Gartenmann, all rights reserved
// This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, version 2.1 of the License.
// 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 www.opensource.org/licenses/lgpl-license.html

namespace Root.Reports {
  // <summary>Structure that defines the properties of a font with metric values.</summary>
  //public class IFontObj {
  //}

  //****************************************************************************************************
  /// <summary>Structure that defines the properties of a font.</summary>
  public class FontProp {
    /// <summary>Font Definition</summary>
    private FontDef _fontDef;

    /// <summary>Size of the font</summary>
    private Double _rSize;

    /// <summary>Bold font</summary>
    private Boolean _bBold;

    /// <summary>Underline</summary>
    private Boolean _bUnderline;

    /// <summary>Italic</summary>
    private Boolean _bItalic;

    /// <summary>Color of the font</summary>
    private Color _color;

    /// <summary>Angle of the rotation in degrees relative to the parent container</summary>
    public Double rAngle = 0.0;

    /// <summary>Reference to the same but registered property object.
    /// If null, it has not yet been used and therefore it is not registered.</summary>
    private FontProp _fontProp_Registered;

    /// <summary>Internal structure used by the formatter</summary>
    private FontPropData _fontPropData;

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Initializes a new font property object</summary>
    /// <param name="fontDef">Font definition</param>
    /// <param name="rSize">Size of the font</param>
    /// <param name="color">Color of the font</param>
    public FontProp(FontDef fontDef, Double rSize, Color color) {
      this._fontDef = fontDef;
      this._rSize = rSize;
      this._color = color;
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Initializes a new font property object</summary>
    /// <param name="fontDef">Font definition</param>
    /// <param name="rSize">Size of the font</param>
    public FontProp(FontDef fontDef, Double rSize) : this(fontDef, rSize, Color.Black) {
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets or sets the bold attribute.</summary>
    public Boolean bBold {
      get { return _bBold; } 
      set {
        System.Diagnostics.Debug.Assert(_fontProp_Registered != this);
        _fontProp_Registered = null;
        _fontPropData = null;
        _bBold = value;
      }
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets or sets the underline attribute.</summary>
    public Boolean bUnderline {
      get { return _bUnderline; } 
      set {
        System.Diagnostics.Debug.Assert(_fontProp_Registered != this);
        _fontProp_Registered = null;
        _fontPropData = null;
        _bUnderline = value;
      }
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets or sets the italic attribute.</summary>
    public Boolean bItalic {
      get { return _bItalic; } 
      set {
        System.Diagnostics.Debug.Assert(_fontProp_Registered != this);
        _fontProp_Registered = null;
        _fontPropData = null;
        _bItalic = value;
      }
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets or sets the color of the font.</summary>
    public Color color {
      get { return _color; } 
      set {
        System.Diagnostics.Debug.Assert(_fontProp_Registered != this);
        _fontProp_Registered = null;
        _fontPropData = null;
        _color = value;
      }
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets or sets the font definition.</summary>
    public FontDef fontDef {
      get { return _fontDef; } 
      set {
        System.Diagnostics.Debug.Assert(_fontProp_Registered != this);
        _fontProp_Registered = null;
        _fontPropData = null;
        _fontDef = value;
      }
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets the font property data.</summary>
    internal FontPropData fontPropData {
      get {
        if (_fontPropData == null) {
          if (fontProp_Registered == this) {
            // FontPropData may be created only for registered FontProp objects
            _fontPropData = fontDef.report.formatter.fontPropData_CreateInstance(this);
          }
          else {
            _fontPropData = fontProp_Registered.fontPropData;
          }
        }
        return _fontPropData;
      }
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets a reference to the same but registered font property object.</summary>
    internal FontProp fontProp_Registered {
      get {
        if (_fontProp_Registered == null) {
          String sKey = _fontDef.sFontName + ";" + _rSize.ToString("F3") + ";" + _color.R + "-" + _color.G + "-" + _color.B + ";" + _bBold + ";" + _bUnderline + ";" + _bItalic;
          _fontProp_Registered = (FontProp)_fontDef.report.ht_FontProp[sKey];
          if (_fontProp_Registered == null) {
            _fontProp_Registered = new FontProp(_fontDef, rSize, _color);
            _fontProp_Registered._bBold = _bBold;
            _fontProp_Registered._bUnderline = _bUnderline;
            _fontProp_Registered._bItalic = _bItalic;
            _fontProp_Registered._fontProp_Registered = _fontProp_Registered;
            _fontDef.report.ht_FontProp.Add(sKey, _fontProp_Registered);
          }
        }
        return _fontProp_Registered;
      }
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets the height of the line feed.</summary>
    public Double rLineFeed {
      get { return _rSize * 2.0; } 
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets the height of the line feed in millimeter.</summary>
    public Double rLineFeedMM {
      get { return RT.rMMFromPoint(rLineFeed); } 
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets or sets the size of the font.</summary>
    public Double rSize {
      get { return _rSize; } 
      set {
        System.Diagnostics.Debug.Assert(_fontProp_Registered != this);
        _fontProp_Registered = null;
        _fontPropData = null;
        _rSize = value;
      }
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets or sets the size of the font in millimeter.</summary>
    public Double rSizeMM {
      get { return RT.rMMFromPoint(_rSize); }
      set { rSize = RT.rPointFromMM(value); }
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets the height of the font in 1/72 inches.</summary>
    /// <returns>Height of the font in 1/72 inches</returns>
    public Double rHeight() {
      return fontPropData.rHeight(this);
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets the width of the specified text with this font in 1/72 inches.</summary>
    /// <param name="sText">Text</param>
    /// <returns>Width of the text in 1/72 inches</returns>
    public Double rWidth(String sText) {
      return fontPropData.rWidth(this, sText);
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Gets the width of the specified text width this font in millimeters</summary>
    /// <param name="sText">Text</param>
    /// <returns>Width of the text in millimeters</returns>
    public Double rWidthMM(String sText) {
      return RT.rMMFromPoint(rWidth(sText));
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Truncates the text to the specified width and adds three dots if necessary.</summary>
    /// <param name="sText">Text</param>
    /// <param name="rWidthMax">width of the text</param>
    /// <returns>Truncated text</returns>
    public String sTruncateText(String sText, Double rWidthMax) {
      if (rWidth(sText) < rWidthMax) {
        return sText;
      }
      rWidthMax -= rWidth("...");

      Double rWidthText = 0;
      Int32 i = 0;
      for (;  i < sText.Length;  i++) {
        Double r = rWidth(sText.Substring(i,1));
        if (rWidthText + r > rWidthMax) {
          break;
        }
        rWidthText += r;
      }
      return sText.Substring(0, i) + "...";
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Truncates the text to the specified width in millimeter</summary>
    /// <param name="sText">Text</param>
    /// <param name="rWidthMaxMM">width of the text in millimeter</param>
    /// <returns>Truncated text</returns>
    public String sTruncateTextMM(String sText, Double rWidthMaxMM) {
      return sTruncateText(sText, RT.rPointFromMM(rWidthMaxMM));
    }

  }


  //****************************************************************************************************
  /// <summary>Structure that defines the properties of a font with metric values.</summary>
  public class FontPropMM : FontProp {
    //----------------------------------------------------------------------------------------------------x
    /// <summary>Initializes a new font property object with metric values</summary>
    /// <param name="fontDef">Font definition</param>
    /// <param name="rSize">Size of the font in millimeter</param>
    /// <param name="color">Color of the font</param>
    public FontPropMM(FontDef fontDef, Double rSize, Color color) : base(fontDef, RT.rPointFromMM(rSize), color) {
    }

    //----------------------------------------------------------------------------------------------------x
    /// <summary>Initializes a new font property object with metric values</summary>
    /// <param name="fontDef">Font definition</param>
    /// <param name="rSize">Size of the font in millimeter</param>
    public FontPropMM(FontDef fontDef, Double rSize) : this(fontDef, rSize, Color.Black) {
    }

  }

}
