// Modellname: monzug10

// Die Makrodefinition '_impexp' dient zur Exportierung
// der Funktionen, Klassen und Variablen innerhalb der Library, 
// wird aber eigentlich nur fuer Windows benoetigt :-(

#ifdef WIN32
  #undef _impexp
  #define _impexp __declspec(dllexport)
#else
  #undef _impexp
  #define _impexp
#endif

#include <stdio.h>
#include "sfxprg.h"     // enthaelt die Funktionen der C-Schnittstelle

int Bestellschwelle =10;//2; //pro Artikel, Bestellmenge entspricht DirAvisSoll der Maschinen
int Bestellmenge =95;//1;

//BDE-A   
const int MaschineL0   = 15;
const int Quelle       = 14;
const int MaschineL1   = 7;
const int MaschineS1 = 5;
const int MaschineL2   = 23;
const int MaschineS2 = 21;
const int BdeBst        = 0; // test mit Bst 0; //10;
const int BdeSchreiben  = 999;

FILE *BdeDatei = NULL;
Ustring BdeDatName("Monzug.BDE");
//BDE-E

class BstBeziehungen : public UserData {
public:
   BstBeziehungen() : UserData() {};
   int Puffer;
   int Lieferant;
   int Kunde;   
   int Partner;
   int Partner2;
   int Bestellzaehler[61]; 

};

void initBstBeziehungen(int bstNr, int puf, int lief, int kun, int part, int part2){
  BstBeziehungen *zBez 	= new BstBeziehungen();
  zBez->Puffer         	= puf;  
  zBez->Lieferant      	= lief;
  zBez->Kunde	   	= kun;
  zBez->Partner    	= part;
  zBez->Partner2    	= part2;
  zBez->Bestellzaehler[10] = 1;
  zBez->Bestellzaehler[20] = 1;
  zBez->Bestellzaehler[30] = 1;
  zBez->Bestellzaehler[60] = 1;
  setBstUserData(bstNr, zBez);
}

void _impexp quelleBestellungAusliefern () {
 ((BstBeziehungen *)BstUserData (3))->Bestellzaehler[ArbeitsplanNr (This)]--;
}

void _impexp quelleBestellungAusliefern2 () {
 ((BstBeziehungen *)BstUserData (19))->Bestellzaehler[ArbeitsplanNr (This)]--;
}

void _impexp init_prog () {
  
  initBstBeziehungen (3, 9, 1, 5, 0, 0);
  bestelleArbeitsplan (10, 1);
  bestelleArbeitsplan (20, 1);
  
  initBstBeziehungen (5, 10, 9, 7, 0, 0);
  bestelleArbeitsplan (10, 9);
  bestelleArbeitsplan (20, 9);

  initBstBeziehungen (7, 11, 10, 15, 15, 0);
  bestelleArbeitsplan (10, 10);
  bestelleArbeitsplan (20, 10);

  initBstBeziehungen (19, 25, 13, 21, 0, 0);
  bestelleArbeitsplan (30, 13);
  bestelleArbeitsplan (60, 13);
  
  initBstBeziehungen (21, 26, 25, 23, 0, 0);
  bestelleArbeitsplan (30, 25);
  bestelleArbeitsplan (60, 25);

  initBstBeziehungen (23, 27, 26, 15, 15, 0);
  bestelleArbeitsplan (30, 26);
  bestelleArbeitsplan (60, 26);

  initBstBeziehungen (15, 0, 11, 0, 7, 23);
  installEvent (ETaarbeiten, 1, "quelleBestellungAusliefern");
  installEvent (ETaarbeiten, 13, "quelleBestellungAusliefern2");
  
  setAnzDirAvisSoll(MaschineL1, Bestellmenge); 
  setAnzDirAvisSoll(MaschineL2, Bestellmenge);
  
  //BDE-A
  DateiMitModellPfad(BdeDatName);
  BdeDatei = fopen (BdeDatName.str(), "w");
  fprintf(BdeDatei, 
  "Zeit_in_H; Ausl_L0; Beleg_L0; Beleg_L1; Beleg_L2; Stoer_S1; Meld_Q; DLZ_A110; Anz_A110; Bestellschwelle;  Bestellmenge \n");
  fclose (BdeDatei);
  installProg (999);
  planeEin (SimTime::convertMinutes (30.0), ETprogramm, BdeBst, BdeSchreiben);
  //BDE-E
}

void _impexp prog_100 () {
  BstBeziehungen *zBez = (BstBeziehungen *)BstUserData(This);
  aufnehmen ();
  if ((AnzBestArbeitsplan(zBez->Puffer, ArbeitsplanNr (This)) < Bestellschwelle) 
      && (zBez->Bestellzaehler[ArbeitsplanNr (This)] == 0)) {
    zBez->Bestellzaehler[ArbeitsplanNr (This)] = AnzDirAvisSoll (This);
    bestelleArbeitsplan (ArbeitsplanNr (This), zBez->Lieferant, 
			zBez->Bestellzaehler[ArbeitsplanNr (This)]);
  }
  arbeiten ();
  if (zBez->Partner){
     syncBst (zBez->Partner);
     syncBst (zBez->Partner);
  }
  ((BstBeziehungen*)BstUserData (zBez->Kunde))->Bestellzaehler[ArbeitsplanNr (This)]--;
  abgeben ();
}

void _impexp prog_200 () {
  BstBeziehungen *zBez = (BstBeziehungen *)BstUserData (This);
  aufnehmen ();
  zBez->Bestellzaehler[ArtikelNr (This)] = 2;
  bestelleArbeitsplan (ArtikelNr (This), zBez->Lieferant);
  bestelleArbeitsplan (ArtikelNr (This) * 3, 27); // Regal 27 ist "Lieferant 2" ;->
  syncBst (zBez->Partner);
  syncBst (zBez->Partner2);
  arbeiten ();
  syncBst (zBez->Partner);
  syncBst (zBez->Partner2);
  abgeben ();
}
//BDE-A
void _impexp prog_999 () {             // BDE-Programm auf Baustein 10
  BdeDatei = fopen (BdeDatName.str(), "a");
  fprintf (BdeDatei, "%5.2f ; %5.2f ; %5.2f ; %5.2f ; %5.2f ; %5.2f ; %i; %5.2f ; %i ; %2i ; %2i \n",
           Modellzeit ().inHours (), MitAuslastung (MaschineL0), MitBelegung(MaschineL0),
           MitBelegung (MaschineL1), MitBelegung (MaschineL2), MitStoerung(MaschineS1), 
           Meldungen(Quelle), MitDurchlaufzeit (110).inMinutes (), 
           AnzArbeitsplaeneAus (110), Bestellschwelle, Bestellmenge);
  fclose (BdeDatei);

  if (Modellzeit () < Modellende ())
    planeDelta (SimTime::convertMinutes (30.0), ETprogramm, BdeBst, BdeSchreiben);
  else
    simAbbruch ();
}
//BDE-E
void _impexp exit_prog () {
}