#define mx_self_is_prod
#include "cb_comp.h"
#include "iec_1131.h"
#ifndef GEN_EMBEDDED
#include "caisse.h"
#else
#include "bibliotheque_epo_caisse.h"
#endif

extern int raise_debug_break(int cpos, int prePostCode, int typeOfBreak, int rank);
#if defined(mx_use_bibliotheque_epo__creation_produit) | defined(mx_verif)
#ifndef GEN_EMBEDDED
#include "bibliotheque_epo/functional/creation_produit/creation_produit.h"
#else
#include "bibliotheque_epo_creation_produit.h"
#endif
#endif
#if defined(mx_use_bibliotheque_epo__convoyeur) | defined(mx_verif)
#ifndef GEN_EMBEDDED
#include "bibliotheque_epo/functional/convoyeur/convoyeur.h"
#else
#include "bibliotheque_epo_convoyeur.h"
#endif
#endif
#if defined(mx_use_bibliotheque_epo__butee) | defined(mx_verif)
#ifndef GEN_EMBEDDED
#include "bibliotheque_epo/functional/butee/butee.h"
#else
#include "bibliotheque_epo_butee.h"
#endif
#endif
#if defined(mx_use_bibliotheque_epo__capteur_presence) | defined(mx_verif)
#ifndef GEN_EMBEDDED
#include "bibliotheque_epo/functional/capteur_presence/capteur_presence.h"
#else
#include "bibliotheque_epo_capteur_presence.h"
#endif
#endif
#if defined(mx_use_bibliotheque_epo__destructeur_produit) | defined(mx_verif)
#ifndef GEN_EMBEDDED
#include "bibliotheque_epo/functional/destructeur_produit/destructeur_produit.h"
#else
#include "bibliotheque_epo_destructeur_produit.h"
#endif
#endif
#if defined(mx_use_bibliotheque_epo__tete_aspirante) | defined(mx_verif)
#ifndef GEN_EMBEDDED
#include "bibliotheque_epo/functional/tete_aspirante/tete_aspirante.h"
#else
#include "bibliotheque_epo_tete_aspirante.h"
#endif
#endif
#if defined(mx_use_bibliotheque_epo__caisse) | defined(mx_verif)
#ifndef GEN_EMBEDDED
#include "bibliotheque_epo/functional/caisse/caisse.h"
#else
#include "bibliotheque_epo_caisse.h"
#endif
#endif
#if defined(mx_use_bibliotheque_epo__basculeur) | defined(mx_verif)
#ifndef GEN_EMBEDDED
#include "bibliotheque_epo/functional/basculeur/basculeur.h"
#else
#include "bibliotheque_epo_basculeur.h"
#endif
#endif


#define SENS_FLUX 1
#define SENS_INVERSE_FLUX -1


/*****************************************************
                             Variables
******************************************************/
CB_Index caisse__num = 0;
CB_Mem_Int *caisse_status_act_prod;
CB_Mem_Float *caisse_m11;
CB_Mem_Float *caisse_m12;
CB_Mem_Float *caisse_m13;
CB_Mem_Float *caisse_m14;
CB_Mem_Float *caisse_m21;
CB_Mem_Float *caisse_m22;
CB_Mem_Float *caisse_m23;
CB_Mem_Float *caisse_m24;
CB_Mem_Float *caisse_m31;
CB_Mem_Float *caisse_m32;
CB_Mem_Float *caisse_m33;
CB_Mem_Float *caisse_m34;
CB_Mem_Float *caisse_m41;
CB_Mem_Float *caisse_m42;
CB_Mem_Float *caisse_m43;
CB_Mem_Float *caisse_m44;
CB_Mem_Float *caisse_deplacementConv;
CB_Mem_Bool *caisse_contact;
CB_Mem_Float *caisse_centreRotX;
CB_Mem_Float *caisse_centreRotZ;
CB_Mem_Float *caisse_centreRotY;
CB_Mem_Int *caisse_sensDeplacement;
CB_Mem_Int *caisse_idConv;
CB_Mem_Bool *caisse_autorisationDeplacement;
CB_Mem_Int *caisse_numero;
CB_Mem_Int *caisse_idProdDessous;
CB_Mem_Float *caisse_oldOtherPx;
CB_Mem_Float *caisse_oldOtherPy;
CB_Mem_Float *caisse_oldOtherPz;
CB_Mem_Float *caisse_oldOtherRx;
CB_Mem_Float *caisse_oldOtherRy;
CB_Mem_Float *caisse_oldOtherRz;
CB_Mem_Float *caisse_vitesseGravite;
CB_Mem_Int *caisse_oldIdConv;
extern int compteur_char_alloc;
extern int compteur_booleen_alloc;
extern int compteur_entier_alloc;
extern int compteur_reel_alloc;

/*****************************************************
                             Variables
******************************************************/
#define status_act_prod (*(long *)(&(caisse_status_act_prod->CB_current_value)))
#define m11 (caisse_m11->CB_current_value)
#define m12 (caisse_m12->CB_current_value)
#define m13 (caisse_m13->CB_current_value)
#define m14 (caisse_m14->CB_current_value)
#define m21 (caisse_m21->CB_current_value)
#define m22 (caisse_m22->CB_current_value)
#define m23 (caisse_m23->CB_current_value)
#define m24 (caisse_m24->CB_current_value)
#define m31 (caisse_m31->CB_current_value)
#define m32 (caisse_m32->CB_current_value)
#define m33 (caisse_m33->CB_current_value)
#define m34 (caisse_m34->CB_current_value)
#define m41 (caisse_m41->CB_current_value)
#define m42 (caisse_m42->CB_current_value)
#define m43 (caisse_m43->CB_current_value)
#define m44 (caisse_m44->CB_current_value)
#define deplacementConv (caisse_deplacementConv->CB_current_value)
#define contact (caisse_contact->CB_current_value)
#define centreRotX (caisse_centreRotX->CB_current_value)
#define centreRotZ (caisse_centreRotZ->CB_current_value)
#define centreRotY (caisse_centreRotY->CB_current_value)
#define sensDeplacement (*(short *)(&(caisse_sensDeplacement->CB_current_value)))
#define idConv (*(long *)(&(caisse_idConv->CB_current_value)))
#define autorisationDeplacement (caisse_autorisationDeplacement->CB_current_value)
#define numero (*(short *)(&(caisse_numero->CB_current_value)))
#define idProdDessous (*(long *)(&(caisse_idProdDessous->CB_current_value)))
#define oldOtherPx (caisse_oldOtherPx->CB_current_value)
#define oldOtherPy (caisse_oldOtherPy->CB_current_value)
#define oldOtherPz (caisse_oldOtherPz->CB_current_value)
#define oldOtherRx (caisse_oldOtherRx->CB_current_value)
#define oldOtherRy (caisse_oldOtherRy->CB_current_value)
#define oldOtherRz (caisse_oldOtherRz->CB_current_value)
#define vitesseGravite (caisse_vitesseGravite->CB_current_value)
#define oldIdConv (*(long *)(&(caisse_oldIdConv->CB_current_value)))

int bibliotheque_epo__caisse()
{
/*****************************************************
                             Internals
******************************************************/
	caisse_status_act_prod = self.Int + 0;
	caisse_m11 = self.Float + 0;
	caisse_m12 = self.Float + 1;
	caisse_m13 = self.Float + 2;
	caisse_m14 = self.Float + 3;
	caisse_m21 = self.Float + 4;
	caisse_m22 = self.Float + 5;
	caisse_m23 = self.Float + 6;
	caisse_m24 = self.Float + 7;
	caisse_m31 = self.Float + 8;
	caisse_m32 = self.Float + 9;
	caisse_m33 = self.Float + 10;
	caisse_m34 = self.Float + 11;
	caisse_m41 = self.Float + 12;
	caisse_m42 = self.Float + 13;
	caisse_m43 = self.Float + 14;
	caisse_m44 = self.Float + 15;
	caisse_deplacementConv = self.Float + 16;
	caisse_contact = self.Bool + 0;
	caisse_centreRotX = self.Float + 17;
	caisse_centreRotZ = self.Float + 18;
	caisse_centreRotY = self.Float + 19;
	caisse_sensDeplacement = self.Int + 1;
	caisse_idConv = self.Int + 2;
	caisse_autorisationDeplacement = self.Bool + 1;
	caisse_numero = self.Int + 3;
	caisse_idProdDessous = self.Int + 4;
	caisse_oldOtherPx = self.Float + 20;
	caisse_oldOtherPy = self.Float + 21;
	caisse_oldOtherPz = self.Float + 22;
	caisse_oldOtherRx = self.Float + 23;
	caisse_oldOtherRy = self.Float + 24;
	caisse_oldOtherRz = self.Float + 25;
	caisse_vitesseGravite = self.Float + 26;
	caisse_oldIdConv = self.Int + 5;
/*****************************************************
                             Component user code
******************************************************/
	if(otherModel == __prelude) {
			/* Initialisation des variables locales de l'instance produit */
			
			deplacementConv = 0.0;
			contact = 0;
			autorisationDeplacement = 1;
			idConv=-1;
		return;
	}

	if(otherModel == __postlude) {
			/* 	Si on ne repose pas sur un solide, on tombe de par sa propre gravité		 */	
			if (contact == 0) 
				moveZBy(myself, vitesseGravite*-1.0);
			
			
			/* 	Déplacement sur convoyeurs si autorisation	 */
			if (autorisationDeplacement == 1 && (idConv>=0)) 
				moveRelativeAnotherBy(myself, idConv, deplacementConv, 0.0, 0.0);
			
			
			/* RAZ des mémoires */
			if (contact == 0) {
				sensDeplacement = 0;
				idProdDessous = -1;
			}
			
		return;
	}

#if defined(mx_use_bibliotheque_epo__creation_produit) | defined(mx_verif)
#ifdef SY_MSW
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__creation_produit__##var)
#else
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__creation_produit__/**/var)
#endif
	if(otherModel == bibliotheque_epo__creation_produit) {
			/*	------------------------------------------------------------	*/
			/*	Information au module de création comme quoi	*/
			/*	  il y a un produit présent dans sa 		*/
			/*		zone géographique			*/
			/*	------------------------------------------------------------	*/
			 
			otherVar(presenceProduit) = 1;
		return;
	}
#undef otherVar
#endif

#if defined(mx_use_bibliotheque_epo__convoyeur) | defined(mx_verif)
#ifdef SY_MSW
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__convoyeur__##var)
#else
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__convoyeur__/**/var)
#endif
	if(otherModel == bibliotheque_epo__convoyeur) {
			/*	------------------------------------------------------------------------	*/
			/*	     Interaction entre le produit et les convoyeurs				*/
			/*	Convention : un convoyeur est toujours orienté de telle 			*/
			/*	  façon à ce que son axe X corresponde au sens du flux				*/
			/*	------------------------------------------------------------------------	*/
			
			
			/* On récupère les données du convoyeur si le centre du produit est inclu dans le volume du convoyeur */
			if ((idConv == -1) || isMyCenterIncludedInXYOfOther(myself, other)) {
				/* Vitesse de déplacement sur le tapis */
				deplacementConv = otherVar(incDeplacementProduit) ;
			
				/* On mémorise le sens de déplacement sur le convoyeur			 */
				if (deplacementConv  > 0.0) sensDeplacement = SENS_FLUX;
				if (deplacementConv  < 0.0) sensDeplacement = SENS_INVERSE_FLUX;
			
				/* On récupère l'identifiant du convoyeur pour pouvoir se déplacer dans son repère		*/
				idConv = other;
				oldIdConv = idConv;
			
				/* Si le convoyeur est sur un transbordeur, ascenceur ... on doit le suivre	 */
				if (otherVar(incrementPositionX) != 0.0) moveXBy(myself, otherVar(incrementPositionX));
				if (otherVar(incrementPositionY) != 0.0) moveYBy(myself, otherVar(incrementPositionY));
				if (otherVar(incrementPositionZ) != 0.0) alignTwoObjectsRelativeThirdZ(myself, other, other);
			
				/* Gestion de la Rotation du Produit sur une table pivotante, plateau tournant ...				*/
				/* On mémorise les centres de rotations pour les transmettres à d'éventuels produits empilés au dessus	*/
				centreRotX = otherVar(centreRotX);
				centreRotY = otherVar(centreRotY);
				centreRotZ = otherVar(centreRotZ);
			
				if ((otherVar(incRotX) != 0.0) || (otherVar(incRotY)!= 0) || (otherVar(incRotZ)!= 0.0))
					rotateBy(myself, otherVar(incRotX), otherVar(incRotY), otherVar(incRotZ), centreRotX, centreRotY, centreRotZ);  
			
			}
			
			/* On repose sur un solide */
			contact = 1;
			
			
			
			
			
		return;
	}
#undef otherVar
#endif

#if defined(mx_use_bibliotheque_epo__butee) | defined(mx_verif)
#ifdef SY_MSW
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__butee__##var)
#else
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__butee__/**/var)
#endif
	if(otherModel == bibliotheque_epo__butee) {
			/*-------------------------------------------------------------------------		*/
			/*	Arret sur butoir				  					*/
			/* Traitement interaction butee avec ou sans callage produit    			*/
			/*	sur butee selon le sens du deplacement 	    					*/
			/*-------------------------------------------------------------------------		*/
			
			
			/* On interdit le déplacement du produit suivant les positions respectives de la butée 
				par rapport au  produit et suivant le sens de deplacement  */
			if ( oldIdConv >= 0 && ((sensDeplacement == SENS_FLUX && (getCenterXInAnother(myself, oldIdConv ) < getCenterXInAnother(other, oldIdConv ))) 
				|| (sensDeplacement == SENS_INVERSE_FLUX && (getCenterXInAnother(myself, oldIdConv ) > getCenterXInAnother(other, oldIdConv )))) ) {
			
				autorisationDeplacement=0;
			 }
		return;
	}
#undef otherVar
#endif

#if defined(mx_use_bibliotheque_epo__capteur_presence) | defined(mx_verif)
#ifdef SY_MSW
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__capteur_presence__##var)
#else
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__capteur_presence__/**/var)
#endif
	if(otherModel == bibliotheque_epo__capteur_presence) {
			/*	------------------------------------------------------------	*/
			/*	Information au composant capteur comme quoi			*/
			/*	  il y a un produit présent dans sa 				*/
			/*		zone géographique						*/
			/*	------------------------------------------------------------	*/
			
			otherVar(detection) = 1;
		return;
	}
#undef otherVar
#endif

#if defined(mx_use_bibliotheque_epo__destructeur_produit) | defined(mx_verif)
#ifdef SY_MSW
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__destructeur_produit__##var)
#else
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__destructeur_produit__/**/var)
#endif
	if(otherModel == bibliotheque_epo__destructeur_produit) {
			/*	Destruction du produit courant si le destructeur est actif		*/
			
			if (otherVar(estActif)) prodKill(myself);
		return;
	}
#undef otherVar
#endif

#if defined(mx_use_bibliotheque_epo__tete_aspirante) | defined(mx_verif)
#ifdef SY_MSW
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__tete_aspirante__##var)
#else
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__tete_aspirante__/**/var)
#endif
	if(otherModel == bibliotheque_epo__tete_aspirante) {
			
			/* on informe l'acteur de la présence d'un produit */
			otherVar(presenceProduit) = 1;
			
			/* on reste en contact seulement si la tête aspire */
			if (otherVar(produitAspire)) {
				moveRelativeAnotherBy(myself, other, otherVar(incrementPositionX), otherVar(incrementPositionY), otherVar(incrementPositionZ));
				contact = 1;
			}
			
		return;
	}
#undef otherVar
#endif

#if defined(mx_use_bibliotheque_epo__caisse) | defined(mx_verif)
#ifdef SY_MSW
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__caisse__##var)
#else
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__caisse__/**/var)
#endif
	if(otherModel == bibliotheque_epo__caisse) {
			/***************************************************************/
			/*	 Intéraction entre deux produits	 			 */
			/***************************************************************/
			
			
			/* On vérifie que le produit à recaler est placé  à côté et non au dessus ou en dessous de l'autre	*/
			if ((getCenterZ(myself) > getCenterZ(other) - (getSizeZ(other)/2.0)) && (getCenterZ(myself) < getCenterZ(other)+(getSizeZ(other)/2.0))) {
				/* On recale celui qui est derriere par rapport au sens de deplacement  */
				if ( (sensDeplacement == SENS_FLUX && (getCenterXInAnother(myself, idConv) < getCenterXInAnother(other, idConv))) 
					|| (sensDeplacement == SENS_INVERSE_FLUX && (getCenterXInAnother(myself, idConv) > getCenterXInAnother(other, idConv))) ) {
					/* Réalignement derriere l'autre si sa vitesse est inférieure */
					if (fabs(deplacementConv ) > fabs(otherVar(deplacementConv)))
						alignTwoObjectsRelativeThirdX(myself, other, idConv);
			
					/* On interdit le déplacement */
					autorisationDeplacement=0;
				 }
			}
			
			 /*	Interaction avec le produit du dessous	*/
			if ((getCenterZ(myself)  > getCenterZ(other)+ (getSizeZ(other) / 2)) 
				&&  ((getCenterX(myself) > getCenterX(other) - (getSizeX(other)/4.0)) && (getCenterX(myself) < getCenterX(other)+(getSizeX(other)/4.0)))
				&&  ((getCenterY(myself) > getCenterY(other) - (getSizeY(other)/4.0)) && (getCenterY(myself) < getCenterY(other)+(getSizeY(other)/4.0))))  {
				/* On se dépace de la même façon que celui du dessous */
				if (idProdDessous == other) {
					moveBy(myself, getPositionX(other)-oldOtherPx, getPositionY(other)-oldOtherPy, getPositionZ(other)-oldOtherPz);
					rotateBy(myself, getAngleX(other)-oldOtherRx, getAngleY(other)-oldOtherRy, getAngleZ(other)-oldOtherRz,
							otherVar(centreRotX), otherVar(centreRotY), otherVar(centreRotZ));
				}
				oldOtherPx=getPositionX(other); oldOtherPy=getPositionY(other); oldOtherPz=getPositionZ(other);
				oldOtherRx=getAngleX(other); oldOtherRy=getAngleY(other); oldOtherRz=getAngleZ(other);
				centreRotX=otherVar(centreRotX); centreRotY=otherVar(centreRotY); centreRotZ=otherVar(centreRotZ);
			
				idProdDessous = other;
			
				/* On repose sur un solide */
				contact = 1;
			
				/* On peut rajouter la ligne de code suivante pour aligner correctement 
					les produits les uns sur les autres ...bien qu'il faudrait aligner en Z par rapport au repere absolu
					et non par rapport au repère relatif si l'on veut être générique.
				=> A adapter suivant les applications et si vraiment nécessaire */
			
				// alignTwoObjectsRelativeThirdZ(myself, other, other); 
				
			}
			
			
			
			
			
			
		return;
	}
#undef otherVar
#endif

#if defined(mx_use_bibliotheque_epo__basculeur) | defined(mx_verif)
#ifdef SY_MSW
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__basculeur__##var)
#else
#define otherVar(var) (otherPointers.mx_acces_bibliotheque_epo__basculeur__/**/var)
#endif
	if(otherModel == bibliotheque_epo__basculeur) {
			
			
			/* Basculement de la pièce */
			if (otherVar(incrementRotation != 0.0)) {
				rotateYBy(myself, otherVar(incrementRotation),otherVar(posInitX),
					 otherVar(posInitY), otherVar(posInitZ));
				autorisationDeplacement = 0;
			} 
			else {
			/* recalage automatique du produit sur des positions fixes */
				CB_Float positionsRecalage[5]={0.0, 90.0, 180.0, 270.0, 360.0};
				CB_Float deltaRecalage = 10.0;
				CB_Int i;
				CB_Float angleCourant;
				angleCourant=getAngleY(myself);  
				for (i=0; i<5; i++) {
					if ((angleCourant - deltaRecalage < positionsRecalage[i]) && (angleCourant + deltaRecalage > positionsRecalage[i])) {
						if (angleCourant != positionsRecalage[i]) {
							rotateYTo(myself, positionsRecalage[i],otherVar(posInitX),otherVar(posInitY), otherVar(posInitZ));
						}
						break;
					 }
				}
			}
			
			/* On repose sur un solide */
			contact = 1;
			
		return;
	}
#undef otherVar
#endif

	free_all_alloc();
	return 0;
}
#undef status_act_prod
#undef m11
#undef m12
#undef m13
#undef m14
#undef m21
#undef m22
#undef m23
#undef m24
#undef m31
#undef m32
#undef m33
#undef m34
#undef m41
#undef m42
#undef m43
#undef m44
#undef deplacementConv
#undef contact
#undef centreRotX
#undef centreRotZ
#undef centreRotY
#undef sensDeplacement
#undef idConv
#undef autorisationDeplacement
#undef numero
#undef idProdDessous
#undef oldOtherPx
#undef oldOtherPy
#undef oldOtherPz
#undef oldOtherRx
#undef oldOtherRy
#undef oldOtherRz
#undef vitesseGravite
#undef oldIdConv

