/// <summary>
 /// Creates a blank frame with only the name set.
 /// </summary>
 /// <param name="name">The display name for the frame.</param>
 private PlayFrame(PlayModel model, String name)
 {
     mPlayModel = model;
       Name = name;
       Notes = "";
       PlayerMovement = new Dictionary<Player, List<LinearMovement>>();
       Triggers = new List<Trigger>();
       DiscFrameMovement = new DiscMovement(this);
       UniqueId = NextUniqueId++;
 }
        /// <summary>
        /// Clones the play model post change.
        /// 
        /// This removes any element which is currrently undone from the list
        /// completely.
        /// </summary>
        /// <param name="playModel">A deep copy clone of the play model.</param>
        public void ModelChange(PlayModel playModel)
        {
            mHistory.RemoveRange(mActionIndex + 1, mHistory.Count - mActionIndex - 1);
              mHistory.Add(new ModelHistoryItem(playModel.Clone()));
              mActionIndex++;

              if (mHistory.Count > mMaxItems)
              {
            mHistory.RemoveAt(0);
              }
        }
        /// <summary>
        /// This constructor takes the previous frame and uses that to determine 
        /// the starting positions for the players.
        /// </summary>
        /// <param name="model"></param>
        /// <param name="previousFrame"></param>
        /// <param name="name"></param>
        /// <param name="nextFrame"></param>
        public PlayFrame(PlayModel model, 
                     PlayFrame previousFrame, 
                     PlayFrame nextFrame, 
                     String name)
            : this(model, name)
        {
            LeftLinkedFrame = previousFrame;
              RightLinkedFrame = nextFrame;

              UpdateFromLeftLink();
              UpdateFromRightLink();
        }
        /// <summary>
        /// Given a play model and a filename this function attempts to write the
        /// entire play out to an xml file using a particular format that the 
        /// viewers can then playback.
        /// 
        /// It is VERY VERY important that the version number is changed each time
        /// any change to the underlying model is made.
        /// </summary>
        /// <param name="model"></param>
        /// <param name="filename"></param>
        public static void OutputModel(PlayModel model, String filename)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
              settings.Indent = false;
              settings.NewLineHandling = NewLineHandling.None;

              using (XmlWriter writer = XmlWriter.Create(filename, settings))
              {

            writer.WriteStartDocument();
            writer.WriteStartElement("play");
            OutputFileHeader(writer);

            foreach (PlayFrame frame in model.GetAllFrames())
            {
              OutputFrame(frame, writer);
            }

            writer.WriteEndElement();
            writer.WriteEndDocument();
              }
        }
 public ModelHistoryItem(PlayModel model)
 {
     this.model = model;
 }
        /// <summary>
        /// Called when we want to undo a change in the model.
        /// </summary>
        /// <param name="clearUndoneModel">Set to false if you want it to
        /// be possible to redo the action.</param>
        internal void Undo(Boolean clearUndoneModel)
        {
            ModelHistoryItem historyItem = mModelHistory.Undo(clearUndoneModel);
              if (historyItem != null)
              {
            mPlayModel = historyItem.model;
            viewPanel.CurrentFrame = mPlayModel.GetFrame(viewPanel.CurrentFrame.UniqueId);
            if (viewPanel.CurrentFrame == null)
            {
              viewPanel.CurrentFrame = mPlayModel.FirstFrame();
            }
            viewPanel.Refresh();

            // Need to tell the frame collection that the model has changed as well
            // since it usually finds out from the ModelChanged function of the
            // main designer form (which isn't called during an undo).
            frameCollection.ModelChanged(mPlayModel);
            frameCollection.CurrentFrameChanged(viewPanel.CurrentFrame);
              }

              // Each time the model changes we check to see whether the undo/redo
              // buttons should be greyed out.
              undoToolStripMenuItem.Enabled = mModelHistory.CanUndo();
              redoToolStripMenuItem.Enabled = mModelHistory.CanRedo();
        }
        /// <summary>
        /// External load routine. Needs to be internal so that it can be called
        /// from the application wide key handler.
        /// </summary>
        internal void LoadPlay()
        {
            using (OpenFileDialog openDialog = new OpenFileDialog())
              {
            openDialog.CheckFileExists = true;
            openDialog.CheckPathExists = true;
            openDialog.Multiselect = false;
            openDialog.Title = "Open Play";
            openDialog.AddExtension = true;
            openDialog.Filter = "Play (*.ply)|*.ply";

            if (openDialog.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
            {
              using (Stream fileStream = openDialog.OpenFile())
              {
            BinaryFormatter bin = new BinaryFormatter();
            mPlayModel = (PlayModel)bin.Deserialize(fileStream);
              }

              frameCollection.ModelChanged(mPlayModel);
              ChangeDisplayedFrame(mPlayModel.FirstFrame());

              // Clear the history as this is a completely new play model.
              mModelHistory.Clear();
              mModelHistory.ModelChange(mPlayModel);
            }
              }
        }
 /// <summary>
 /// Called from the designer form whenever the model changes.
 /// 
 /// Don't seem to need to automatically refresh. Presumably because
 /// setting the background image causes a refresh itself.
 /// </summary>
 internal void ModelChanged(PlayModel model)
 {
     mPlayModel = model;
       CreateBackgroundImage();
 }
 public VideoOutputter(String videoFile, PlayModel model)
 {
     mModel = model;
       mVideoFile = videoFile;
 }