#include "Protocol_impl.h"

#include "Protocol_view.h"
#include "Path.h"
#include "Path.h"

#include "Project.h"
#include "Project_kit.h"

#include "Model.h"
#include "Model_kit.h"

#include <fstream>
#include <sstream>
#include <string>

#include "Create.h"

#ifdef WIN32
#pragma warning (disable : 4355)
#endif

//
//  Do not foget set_model (0) when model deleted.
//

namespace MM
{

Protocol_impl::
Protocol_impl (Text const& file)
:
    file_      (file),
    view_      (prototype <Protocol_view> ()),
    cursor_    (*this),
    model_     ( Model::none ()),
    model_tmp_ (&Model::none ())
{
    //load (Path::protocol () + "! default.protocol");
    INVARIANT;
}

Model_proxy & Protocol_impl::
model ()
{
    INVARIANT;

    /*if (!model_.kit().is_locked())
    {
        if (model_tmp_ != &Model::none ())
        {
            model_.set_model (model_tmp_);
            model_tmp_ = &Model::none ();
        }
    }//*/

    INVARIANT;
    return model_;
}

void Protocol_impl::
set_model (Model & model)
{
    INVARIANT;
    /*if (model_.real_model () != &Model::none () && model_.kit().is_locked())
        model_tmp_= &model;
    else
    {
        model_tmp_ = &Model::none ();
        model_.set_model (&model);

        for (int i=0;  i<step_count();  ++i)
            step(i).update ();
    }//*/
    if (model_.real_model() == &Model::none () || !model_.kit().is_locked())
    {
        model_.set_model (&model);

        for (int i=0;  i<stage_count();  ++i)
            stage(i).update ();
    }

    INVARIANT;
}

void Protocol_impl::
load (Text const& filename)
{
    INVARIANT;

    using namespace std;
    ifstream    in (filename.c_str());
    if (!in.is_open())
        FLAW (Text("Can not open file " + filename));

    string      line;
    stage_.clear();

    while (getline(in, line))
    {
        string          item_type;
        istringstream   stream (line);
        stream >> item_type;

        if (item_type.empty())
            continue;
        
        stage_.adopt (Protocol_stage::create (line.c_str()));
    }

    cursor().first ();
    INVARIANT;
}

bool Protocol_impl::
invariant () const
{
    return model_tmp_ != 0 
        //&& model_.real_model () != 0
        ;
}

}//MM
