#ifndef CRYSTAL_BUILDER_IMPL_H
#define CRYSTAL_BUILDER_IMPL_H

#ifndef CRYSTAL_BUILDER_H
#include "Crystal_builder.h"
#endif

#ifndef VECTOR_3D_IMPL_H
#include "Vector_3D_impl.h"
#endif

#ifndef GRID_3D_H
#include "Grid_3D.h"
#endif

#ifndef ARRAY_OF_OWN_H
#include "Array_of_own.h"
#endif

#ifndef ARBITRARY_ATOM_GROUP_H
#include "Arbitrary_atom_group.h"
#endif

#ifndef EDITOR_H
#include "Editor.h"
#endif

#ifndef DBC_H
#include "DbC.h"
#endif

namespace MM
{
//class Model;
class Box;
class Prototype;

class Crystal_builder_impl 
    : public Crystal_builder, public Editor, protected DbC
{
    Box &                   box () const;

    bool                    use_PBC_;
    int                     a_copies_, b_copies_, c_copies_;

    Model &                 model_;
    Arbitrary_atom_group    cell_copy_;
    Arbitrary_atom_group    cell_node_;
    Arbitrary_atom_group    octahedral_hole_;
    Arbitrary_atom_group    tetrahedral_hole_;

public:
    // Editor
    virtual Text const&     name () const;
    virtual void            handle_start_editing    ();
    virtual void            handle_finish_editing   ();
    virtual void            handle_cancel_editing   ();
    virtual void            handle_activate_editing ();
    //

    explicit            Crystal_builder_impl (Prototype const &);
    explicit            Crystal_builder_impl (Model & model);
    Crystal_builder *   clone (Model & model) const;

    Model &             model ()        {return model_;}

    Vector_3D const &   a () const;
    Vector_3D const &   b () const;
    Vector_3D const &   c () const;

    void                set (Vector_3D const & a, 
                             Vector_3D const & b, 
                             Vector_3D const & c);

    double              a_mod () const;//fix remove
    double              b_mod () const;
    double              c_mod () const;

    double              alpha () const;//fix remove
    double              beta  () const;
    double              gamma () const;

    void                set (double new_a,//fix remove
                             double new_b,    
                             double new_c,
                             double new_alpha, 
                             double new_beta, 
                             double new_gamma);//*/

    int                 a_copies () const               {return a_copies_;}
    int                 b_copies () const               {return b_copies_;}
    int                 c_copies () const               {return c_copies_;}
    void                set_number_of_copies (int a, int b, int c);
    //void                update_copies ();

    //bool                use_PBC () const                {return use_PBC_;}
    //void                set_use_PBC (bool use)          {use_PBC_ = use;}
    bool                use_PBC () const;
    void                set_use_PBC (bool use);

    //bool                show_images () const           {return image_.size()>1;}
    //void                set_show_images (bool show);

    bool                show_border  () const           {return true;}
    char const *        border_style () const           {return "Wireframe";}

    void                expand_model     ();
    void                convert_from_fractional_to_cartesian ();
    void                fit_box ();

    Atom_group &        cell_copy       () {return cell_copy_;}
    Atom_group &        cell_node       () {return cell_node_;}
    Atom_group &        octahedral_hole () {return octahedral_hole_;}
    Atom_group &        tetrahedral_hole() {return tetrahedral_hole_;}

protected:
    void                update_images ();
    //void                hide_cell_copies ();
    void                show_cell_copies ();
};

}//MM

#endif //CRYSTAL_BUILDER_IMPL_H
