CanadianMachines / CanadianExperienceLib / Picture.cpp
Picture.cpp
Raw
/**
 * @file Picture.cpp
 * @author Charles B. Owen
 */
#include "pch.h"
#include <wx/stdpaths.h>

#include "Picture.h"
#include "PictureObserver.h"
#include "Actor.h"

using namespace std;


/**
 * Constructor
*/
Picture::Picture()
{
}


/**
 * Set the current animation time
 *
 * This forces the animation of all
 * objects to the current animation location.
 * @param time The new time.
 */
void Picture::SetAnimationTime(double time)
{
    mTimeline.SetCurrentTime(time);
    UpdateObservers();

    for (auto actor : mActors)
    {
        actor->GetKeyframe();
    }
}

/**
 * Get the current animation time.
 * @return The current animation time
 */
double Picture::GetAnimationTime()
{
    return mTimeline.GetCurrentTime();
}

/**
 * Add an observer to this picture.
 * @param observer The observer to add
 */
void Picture::AddObserver(PictureObserver* observer)
{
    mObservers.push_back(observer);
}

/**
 * Remove an observer from this picture
 * @param observer The observer to remove
 */
void Picture::RemoveObserver(PictureObserver* observer)
{
    auto loc = find(std::begin(mObservers), std::end(mObservers), observer);
    if (loc != std::end(mObservers))
    {
        mObservers.erase(loc);
    }
}

/**
 * Update all observers to indicate the picture has changed.
 */
void Picture::UpdateObservers()
{
    for (auto observer : mObservers)
    {
        observer->UpdateObserver();
    }
}

/**
 * Draw this picture on a device context
 * @param graphics The device context to draw on
 */
void Picture::Draw(std::shared_ptr<wxGraphicsContext> graphics)
{
    for (auto actor : mActors)
    {
        actor->Draw(graphics);
    }
}

/**
 * Add an actor to this drawable.
 * @param actor Actor to add
 */
void Picture::AddActor(std::shared_ptr<Actor> actor)
{
    mActors.push_back(actor);
    actor->SetPicture(this);
}


/**
* Save the picture animation to a file
* @param filename File to save to.
*/
void Picture::Save(const wxString& filename)
{
    wxXmlDocument xmlDoc;

    auto root = new wxXmlNode(wxXML_ELEMENT_NODE, L"anim");
    xmlDoc.SetRoot(root);

    // Save the timeline animation into the XML
    mTimeline.Save(root);

    //
    // It is possible to add attributes to the root node here
    //
	// create a new child node
	auto machine1 = new wxXmlNode(wxXML_ELEMENT_NODE, L"Machine1");
	machine1->AddAttribute(L"Number", wxString::Format(wxT("%i"), mMachine1->GetMachineNumber()));
	machine1->AddAttribute(L"StartTime", wxString::Format(wxT("%i"), mMachine1->GetStartTime()));
	machine1->AddAttribute(L"EndTime", wxString::Format(wxT("%i"), mMachine1->GetEndTime()));

	auto machine2 = new wxXmlNode(wxXML_ELEMENT_NODE, L"Machine2");
	machine2->AddAttribute(L"Number", wxString::Format(wxT("%i"), mMachine2->GetMachineNumber()));
	machine2->AddAttribute(L"StartTime", wxString::Format(wxT("%i"), mMachine2->GetStartTime()));
	machine2->AddAttribute(L"EndTime", wxString::Format(wxT("%i"), mMachine2->GetEndTime()));

	root->AddChild(machine1);
	root->AddChild(machine2);

    if(!xmlDoc.Save(filename, wxXML_NO_INDENTATION))
    {
        wxMessageBox(L"Write to XML failed");
        return;
    }
}



/**
* Load a picture animation from a file
* @param filename file to load from
*/
void Picture::Load(const wxString& filename)
{
    wxXmlDocument xmlDoc;
    if(!xmlDoc.Load(filename))
    {
        wxMessageBox(L"Unable to load Animation file");
        return;
    }

    // Get the XML document root node
    auto root = xmlDoc.GetRoot();

    // Load the animation from the XML
    mTimeline.Load(root);

    //
    // It is possible to load attributes from the root node here
    //
    // mSomething = root->GetAttribute(L"something", L"default");
	auto child = root->GetChildren();
	for( ; child; child=child->GetNext())
	{
		auto name = child->GetName();
		if(name == L"Machine1")
		{
			mMachine1->SetNumber(wxAtoi(child->GetAttribute(L"Number", L"1")));
			mMachine1->SetStartTime(wxAtoi(child->GetAttribute(L"StartTime", L"30")));
			mMachine1->SetEndTime(wxAtoi(child->GetAttribute(L"EndTime", L"150")));
		}
		else if(name == L"Machine2")
		{
			mMachine2->SetNumber(wxAtoi(child->GetAttribute(L"Number", L"2")));
			mMachine2->SetStartTime(wxAtoi(child->GetAttribute(L"StartTime", L"150")));
			mMachine2->SetEndTime(wxAtoi(child->GetAttribute(L"EndTime", L"300")));
		}
	}
    SetAnimationTime(0);
    UpdateObservers();
}