#pragma once
#ifndef _COMMAND_
#define _COMMAND_
#include"read_write.h"
#include"variant.h"
namespace EVO {
	void Exchange_command(int    nant_o[],                  // total number of atoms and types
		int    typenum_o[],               // number of each type 
		double xyz_o[][3],                // atomic coordinates
		double xyz_e[][3],
		int ExgNum,
		int Num1[],
		int Num2[]
	);
	void Strain_command(char   mode[],
		double vec_o[3][3],               // lattice vectors
		double vec_e[3][3],
		double strain0, double strain1, double strain2,
		double strain3, double strain4, double strain5);


	void Ripple_command(int    nant_o[],                  // total number of atoms and types
		double xyz_o[][3],                // atomic coordinates
		double xyz_e[][3],
		int temp,
		double angle_1,
		double angle_2);

	//The random move operator moves all atomsĄŻ positions randomly, keeping the lattice vectors unchanged
	void Randmove_command(int    nant_o[],
		double xyz_o[][3],
		double xyz_e[][3],
		int num,
		double dxyz
	);

	//This operator slips a group of atoms by a random distance along a random direction that is parallel to a specific plane
	void Slip_command(int    nant_o[],                  // total number of atoms and types
		double xyz_o[][3],                // atomic coordinates
		double xyz_e[][3],
		double zlower, double ydisp, double xlower,
		double zdisp, double ylower, double xdisp);

	void Twist_command(int    nant_o[],                  // total number of atoms and types
		double xyz_o[][3],                // atomic coordinates
		double xyz_e[][3],
		char axis,
		double angle);

	void Rotation_command(double vec_o[3][3],               // lattice vectors
		double vec_e[3][3],
		double angle1,
		double angle2,
		double angle3);

	void Crossover_command(double& latt1_o,
		double& latt2_o,                  // Scaling Lattice parameter 
		double& latt_e,
		int    nant_o[],                    // total number of atoms and types
		int    typenum_o[],               // number of each type
		double vec1_o[3][3],
		double vec2_o[3][3],              // lattice vectors
		double vec_e[3][3],
		double xyz1_o[][3],
		double xyz2_o[][3],               // atomic coordinates
		double xyz_e[][3],
		char axis,
		double segment);

	void Stripple_command(int    nant_o[],                    // total number of atoms and types
		double vec_o[3][3],               // lattice vectors
		double vec_e[3][3],
		double xyz_o[][3],                // atomic coordinates
		double xyz_e[][3],
		double strain0, double strain1, double strain2,
		double strain3, double strain4, double strain5,
		int temp,
		double angle_1, double angle_2);

	void Permustrain_command(int    nant_o[],                    // total number of atoms and types
		int    typenum_o[],
		double vec_o[3][3],               // lattice vectors
		double vec_e[3][3],
		double xyz_o[][3],                // atomic coordinates
		double xyz_e[][3],
		double strain0, double strain1, double strain2,
		double strain3, double strain4, double strain5,
		int ExgNum,
		int num1[], int num2[]);

	void Rotstrain_command(
		double vec_o[3][3],               // lattice vectors
		double vec_e[3][3],
		double angle1,
		double angle2,
		double angle3,
		char mode[],
		double strain);

	void Variant_singer_parent_C(char POSCAR_Parent[], char POSCAR_Child[], char method[]);

	int Variant_two_parent_C(char POSCAR_Parent1[], char POSCAR_Parent2[], char POSCAR_Child[]);
}
#endif
