#include "Module.h"

#include "Peep.h"
#include "Main_window.h"
#include "Bond.h"
#include "Bond_kit.h"
#include "Visual_bond.h"

#include "Project.h"
#include "Atom.h"
#include "Atom_kit.h"
#include "Model.h"
#include "Model_kit.h"

#include "Abstracts.h"
#include "Create.h"
#include "Command_template.h"

#include "Model_RM_window.h"
#include "Model_RM_widget.h"

namespace MM
{

class Module_view : public Module
{
    static Module_view      singleton_;
                            Module_view() ;
    void                    init ();

    void    wireframe_CPK  ()   {setup_style (Visual_style::wireframe_CPK);}
    void    wireframe      ()   {setup_style (Visual_style::wireframe);}
    void    stick          ()   {setup_style (Visual_style::stick);}
    void    CPK            ()   {setup_style (Visual_style::CPK);}
    void    ball_and_stick ()   {setup_style (Visual_style::ball_and_stick);}


    void                    setup_style (Visual_style style);
    int                     view_index (Model & model);
};
Module_view  Module_view::singleton_;


Module_view::Module_view () : Module ("View") { }

void  Module_view::
init ()
{
    adopt_command (create_command (*this, &Module_view::wireframe))
        .set_menu        ("&View", "&Wire Frame")
        .set_tool_tip    ("Wire Frame")
        .set_icon        ("Fast View", "wireframe.png");

    adopt_command (create_command (*this, &Module_view::wireframe_CPK))
        .set_menu        ("&View", "Wire Frame &CPK")
        .set_tool_tip    ("CPK Wire Frame")
        .set_icon        ("Fast View", "wireframe_CPK.png");

    adopt_command (create_command (*this, &Module_view::ball_and_stick))
        .set_menu        ("&View", "&Ball and Stick")
        .set_tool_tip    ("Ball and Stick")
        .set_icon        ("Fast View", "ball_and_stick.png");

    adopt_command (create_command (*this, &Module_view::stick))
        .set_menu        ("&View", "&Stick")
        .set_tool_tip    ("Stick")
        .set_icon        ("Fast View", "stick.png");

    adopt_command (create_command (*this, &Module_view::CPK))
        .set_menu        ("&View", "&CPK")
        .set_tool_tip    ("CPK")
        .set_icon        ("Fast View", "CPK.png");

    insert_menu_separator ("&View");

    adopt_command (prototype <Set_Z_viewpoint> ().clone())
        .set_menu        ("&View", "Set &Z viewpoint")
        .set_tool_tip    ("Setup viewpoint along Z axis. X - right. Y - up.")
        .set_icon        ("Fast View", "flush_camera.png");

    insert_menu_separator ("&View");

}


void  Module_view::
setup_style (Visual_style style)
{
    //Model_RM_window * window = (Model_RM_window *)
    //    Main_window::singleton()->current_model_window();
    //Model & model = window->model();
    Model & model = Project::singleton ().current_model ();

    int count = model.atom_count ();

    if (count == 0)
        return;

    int i;
    bool no_selection = true;
    int index = view_index (model);

    model.atom_prototype().kit().visual().view(index).set_style (style);
    model.bond_prototype().kit().visual().view(index).set_style (style);

    for (i=0;  i<count;  ++i)
    {
        Atom_kit &     atom = model.atom(i).kit();
        Visual_atom &  view = atom.visual().view (index);

        if (atom.is_selected())
        {
            view.set_style (style);
            no_selection = false;
        }
    }

    count = model.bond_count ();

    for (i=0;  i<count;  ++i)
    {
        Bond_kit &     bond = model.bond(i).kit();
        Visual_bond &  view = bond.visual().view (index);

        if (bond.is_selected())
        {
            view.set_style (style);
            no_selection = false;
        }
    }

    if (no_selection)
    {
        count = model.atom_count ();

        for (i=0;  i<count;  ++i)
        {
            Atom_kit &     atom = model.atom(i).kit();
            Visual_atom &  view = atom.visual().view (index);
            view.set_style (style);
        }

        count = model.bond_count ();

        for (i=0;  i<count;  ++i)
        {
            Bond_kit &     bond = model.bond(i).kit();
            Visual_bond &  view = bond.visual().view (index);
            view.set_style (style);
        }
    }
}

int Module_view::
view_index (Model & model)
{
    int count = model.atom_count ();
    //int index;

    if (count > 0)
    {
        Model_RM_window * model_window = (Model_RM_window *)
            Main_window::singleton()->current_model_window();

        OpenRMWidget * model_widget = model_window->current_model_widget ();

        Atom_kit &     atom = model.atom(0).kit();
        Visual_atom_composite & visual_atom = atom.visual();
        //int visual_atom_count = visual_atom.count();

        {
            Visual_atom &  view = visual_atom.view (0);
            OpenRM_atom &  rm_atom = (OpenRM_atom &)view;
            OpenRMWidget * atom_widget = rm_atom.rm_widget ();

            if (model_widget == atom_widget)
                return 0;
        }
        //if (visual_atom_count > 1)
        {
            Visual_atom &  view = visual_atom.view (1);
            OpenRM_atom &  rm_atom = (OpenRM_atom &)view;
            OpenRMWidget * atom_widget = rm_atom.rm_widget ();

            if (model_widget == atom_widget)
                return 1;
        }
    }

    FLAW ("@ Module_view::view_index");
    return -1;
}

}//MM
