using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using RainmeterStudio.Core.Documents;
using RainmeterStudio.Core.Model;
using RainmeterStudio.Core.Model.Events;
using RainmeterStudio.Core.Storage;
namespace RainmeterStudio.Business
{
///
/// Document manager
///
public class DocumentManager
{
#region Events
///
/// Triggered when a document is opened
///
public event EventHandler DocumentOpened;
///
/// Triggered when a document is closed
///
public event EventHandler DocumentClosed;
#endregion
#region Properties
///
/// Gets a list of factories
///
public IEnumerable Factories { get { return _factories; } }
///
/// Gets a list of editors
///
public IEnumerable Editors { get { return _editors; } }
///
/// Gets a list of storages
///
public IEnumerable Storages { get { return _storages; } }
///
/// Gets a list of document templates
///
public IEnumerable DocumentTemplates { get { return _templates; } }
#endregion
#region Private fields
private List _factories = new List();
private List _editors = new List();
private List _storages = new List();
private List _templates = new List();
#endregion
#region Initialization
///
/// Initializes this document manager
///
public DocumentManager()
{
}
///
/// Registers a document editor factory
///
/// Document editor factory
public void RegisterEditorFactory(IDocumentEditorFactory factory)
{
_factories.Add(factory);
}
///
/// Registers a document storage
///
/// The storage
public void RegisterStorage(IDocumentStorage storage)
{
_storages.Add(storage);
}
///
/// Registers a document template
///
/// The document template
public void RegisterTemplate(IDocumentTemplate template)
{
_templates.Add(template);
}
#endregion
#region Document operations
///
/// Creates a new document in the specified path, with the specified format, and opens it
///
///
///
public IDocumentEditor Create(IDocumentTemplate format)
{
// Create document
var document = format.CreateDocument();
document.IsDirty = true;
// Find and create editor
IDocumentEditor editor = CreateEditor(document);
// Trigger event
if (DocumentOpened != null)
DocumentOpened(this, new DocumentOpenedEventArgs(editor));
return editor;
}
///
/// Opens the specified document
///
/// The path to the file to open
public IDocumentEditor Open(string path)
{
// Try to open
IDocument document = Read(path);
// Create factory
var editor = CreateEditor(document);
// Trigger event
if (DocumentOpened != null)
DocumentOpened(this, new DocumentOpenedEventArgs(editor));
return editor;
}
///
/// Saves a document
///
/// The document
public void Save(IDocument document)
{
// Find a storage
var storage = FindStorage(document);
if (document.Reference == null)
throw new ArgumentException("Reference cannot be empty");
// Save
storage.Write(document.Reference.Path, document);
// Clear dirty flag
document.IsDirty = false;
}
///
/// Saves the document as
///
/// Path
/// Document
public void SaveAs(string path, IDocument document)
{
// Find a storage
var storage = FindStorage(document);
// Save
storage.Write(path, document);
// Update reference
document.Reference = new Reference(Path.GetFileName(path), path);
// Clear dirty flag
document.IsDirty = false;
}
///
/// Saves a copy of the document
///
/// Path
/// Document
public void SaveACopy(string path, IDocument document)
{
// Find a storage
var storage = FindStorage(document);
// Save
storage.Write(path, document);
}
///
/// Closes a document editor
///
///
public void Close(IDocumentEditor editor)
{
// Remove from list of opened editors
_editors.Remove(editor);
// Close event
if (DocumentClosed != null)
DocumentClosed(this, new DocumentClosedEventArgs(editor));
}
#endregion
#region Private functions
///
/// Attempts to create an editor for the document
///
/// The document
/// Thrown if failed to create editor
/// The editor
private IDocumentEditor CreateEditor(IDocument document)
{
IDocumentEditor editor = null;
foreach (var factory in Factories)
if (factory.CanEdit(document.GetType()))
{
editor = factory.CreateEditor(document);
break;
}
if (editor == null)
throw new ArgumentException("Failed to create editor.");
_editors.Add(editor);
return editor;
}
///
/// Attempts to read a document
///
/// Path of file
/// Thrown when failed to open the document
///
private IDocument Read(string path)
{
IDocument document = null;
foreach (var storage in Storages)
if (storage.CanRead(path))
{
document = storage.Read(path);
break;
}
// Failed to open
if (document == null)
throw new ArgumentException("Failed to open document.");
return document;
}
///
/// Attempts to find a storage for the specified document
///
///
///
private IDocumentStorage FindStorage(IDocument document)
{
IDocumentStorage storage = null;
foreach (var s in Storages)
if (s.CanWrite(document.GetType()))
{
storage = s;
break;
}
if (storage == null)
throw new ArgumentException("Failed to find storage object.");
return storage;
}
#endregion
}
}