text: ﻿namespace MiniUML.Plugins.UmlClassDiagram.Controls.ViewModel.Shape
  {
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Windows;
    using System.Xml;
    using MiniUML.Model.ViewModels;
    using MiniUML.Model.ViewModels.Shapes;
    using MiniUML.Plugins.UmlClassDiagram.Controls.ViewModel.Shape.Base;
    using MiniUML.Plugins.UmlClassDiagram.Controls.ViewModel.UmlElements;
    using MiniUML.Plugins.UmlClassDiagram.Converter;
  
    /// <summary>
    /// This class implements the viewmodel for Uml shapes
    /// with a square or rectangulare shape that users can
    /// draw on a UML canvas. Typically, these are class or
    /// table shapes or other items.
    /// </summary>
    public class UmlSquareShapeViewModel : UmlShapeBaseViewModel
    {
      #region fields
      private bool mHorizontalLine = false;
      private string mShapeImageUrl = string.Empty;
      private string mStereotype = string.Empty;
      #endregion fields
  
      #region constructor
      /// <summary>
      /// Standard contructor hidding XElement constructor
      /// </summary>
      public UmlSquareShapeViewModel(IShapeParent parent,
                                      UmlTypes umlType)
        : base(parent,
               ShapeViewModelKey.SquareShape, ShapeViewModelSubKeys.None,
               umlType)
      {
      }
      #endregion constructor
  
      #region properties
      /// <summary>
      /// Get/set property to determine whether the view should show
      /// a horizonal line or not.
      /// </summary>
      public bool HorizontalLine
      {
        get
        {
          return this.mHorizontalLine;
        }
  
        set
        {
          if (this.mHorizontalLine != value)
          {
            this.mHorizontalLine = value;
            this.NotifyPropertyChanged(() => this.HorizontalLine);
          }
        }
      }
  
      /// <summary>
      /// Get/set property to determine whether the view should show
      /// an additional image or not.
      /// 
      /// Todo: This should be implemented via converter based on UmlShapeKey ???
      /// </summary>
      public string ShapeImageUrl
      {
        get
        {
          return this.mShapeImageUrl;
        }
  
        set
        {
          if (this.mShapeImageUrl != value)
          {
            this.mShapeImageUrl = value;
            this.NotifyPropertyChanged(() => this.ShapeImageUrl);
          }
        }
      }
  
      /// <summary>
      /// Get/set stereotype for the corresponding shape displayed in the view.
      /// </summary>
      public string Stereotype
      {
        get
        {
          return this.mStereotype;
        }
  
        set
        {
          if (this.mStereotype != value)
          {
            this.mStereotype = value;
            this.NotifyPropertyChanged(() => this.Stereotype);
          }
        }
      }
      #endregion properties
  
      #region methods
      /// <summary>
      /// Reaf shape data from XML stream and return it.
      /// </summary>
      /// <param name="reader"></param>
      /// <param name="parent"></param>
      /// <param name="umlType"></param>
      /// <returns></returns>
      public static UmlSquareShapeViewModel ReadDocument(XmlReader reader,
                                                         IShapeParent parent,
                                                         UmlTypes umlType)
      {
        UmlSquareShapeViewModel ret = UmlElementDataDef.CreateShape(umlType, new Point(UmlTypeToStringConverter.DefaultX,
                                                                                       UmlTypeToStringConverter.DefaultY), parent)
                                                                                       as UmlSquareShapeViewModel;
  
        reader.ReadToNextSibling(ret.UmlDataTypeString);
  
        while (reader.MoveToNextAttribute())
        {
          if (ret.ReadAttributes(reader.Name, reader.Value) == false)
          {
            if (reader.Name.Trim().Length > 0 && reader.Name != UmlShapeBaseViewModel.XmlComment)
              throw new ArgumentException("XML node:'" + reader.Name + "' as attribute of '" + ret.XElementName + "' is not supported.");
          }
        }
  
        // Read common model information (eg. comments)
        UmlShapeBaseViewModel.ReadDocument(reader, ret);
  
        return ret;
      }
  
      /// <summary>
      /// Persist the contents of this object into the given
      /// parameter <paramref name="writer"/> object.
      /// </summary>
      /// <param name="writer"></param>
      public override void SaveDocument(System.Xml.XmlWriter writer,
                                        IEnumerable<ShapeViewModelBase> root)
      {
        writer.WriteStartElement(this.mElementName);
  
        this.SaveAttributes(writer);
  
        // Save common model information (eg. comments)
        base.SaveDocument(writer);
  
        if (root != null)
        {
          foreach (var item in root)
          {
            item.SaveDocument(writer, item.Elements());
          }
        }
  
        writer.WriteEndElement();
      }
  
      /// <summary>
      /// Save the attribute values of this class to XML.
      /// </summary>
      /// <param name="writer"></param>
      protected override void SaveAttributes(System.Xml.XmlWriter writer)
      {
        base.SaveAttributes(writer);
  
        writer.WriteAttributeString("Stereotype", string.Format("{0}", this.Stereotype));
      }
  
      protected override bool ReadAttributes(string readerName, string readerValue)
      {
        if (base.ReadAttributes(readerName, readerValue) == true)
          return true;
  
        switch (readerName)
        {
          case "Stereotype":
            this.Stereotype = readerValue;
          return true;
        }
  
        return false;
      }
      #endregion methods
    }
  }
  