FUNCTION_BLOCK "FB_Visu_JamStorage"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT
      nInJamCount : UInt;
   END_VAR

   VAR_IN_OUT
      arInOutJam : Array[*] of "stCarrier";   // Jam Daten
      stInOutHMIJam : "UDT_Visu_Jam_List";
      stInOutHMIData : "UDT_HMI_StorageData";   // Jam Daten HMI Schnittstelle
   END_VAR

   VAR
      xReInit : Bool;
      nUpperBound : Int;
   END_VAR

   VAR_TEMP
      nIdx : Int;
      nIdxMerker : Int;
   END_VAR


BEGIN
	// Hier werden die Carrierlisten für die Visu erstellt
	// Auf Knopfdruck am HMI werden Aktionen durchgeführt, um die Liste zu scrollen
	// Aktuell werden immer 10 Carrier gleichzeitig angezeigt

	#stInOutHMIJam.#upperBound := DINT_TO_INT(UPPER_BOUND(ARR := #arInOutJam, DIM := 1));
	#nUpperBound := DINT_TO_INT(UPPER_BOUND(ARR := #arInOutJam, DIM := 1));
	REGION Jam Daten Liste
	    // Beim ersten Aufruf nach reinit ausführen, damit Daten drinstehen
	    IF NOT #xReInit THEN
	        #stInOutHMIJam.nIndex := 1;
	        #nIdxMerker := #stInOutHMIJam.nIndex;
	        FOR #nIdx := 1 TO 10 DO
	            #stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
	            #nIdxMerker += 1;
	            IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
	                EXIT;
	            END_IF;
	        END_FOR;
	        #xReInit := TRUE;
	    END_IF;

	    // Wenn nichts an der Liste gemacht wird, Daten nur aktualisieren
	    IF NOT #stInOutHMIJam.#DecOne AND NOT #stInOutHMIJam.#DecFive AND NOT #stInOutHMIJam.#IncOne AND NOT #stInOutHMIJam.#IncFive AND NOT #stInOutHMIJam.#ScrollEnd AND NOT #stInOutHMIJam.#ScrollStart THEN
	        #nIdxMerker := #stInOutHMIJam.nIndex;
	        FOR #nIdx := 1 TO 10 DO
	            #stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
	            #nIdxMerker += 1;
	            IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
	                EXIT;
	            END_IF;
	        END_FOR;
	    END_IF;

	    // Liste um eins nach oben bewegen
	    IF #stInOutHMIJam.#DecOne THEN
	        #stInOutHMIJam.#nIndex -= 1;
	        IF #stInOutHMIJam.#nIndex < 1 THEN
	            #stInOutHMIJam.#nIndex := 1;
	        END_IF;

	        #nIdxMerker := #stInOutHMIJam.nIndex;

	        FOR #nIdx := 1 TO 10 DO
	            #stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
	            #nIdxMerker += 1;
	            IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
	                EXIT;
	            END_IF;
	        END_FOR;

	        #stInOutHMIJam.#DecOne := FALSE;
	    END_IF;

	    // Liste um fünf nach oben bewegen
	    IF #stInOutHMIJam.#DecFive THEN
	        #stInOutHMIJam.#nIndex -= 5;
	        IF #stInOutHMIJam.#nIndex < 1 THEN
	            #stInOutHMIJam.#nIndex := 1;
	        END_IF;

	        #nIdxMerker := #stInOutHMIJam.nIndex;

	        FOR #nIdx := 1 TO 10 DO
	            #stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
	            #nIdxMerker += 1;
	            IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
	                EXIT;
	            END_IF;
	        END_FOR;
	        #stInOutHMIJam.#DecFive := FALSE;
	    END_IF;

	    // Liste um eins nach unten bewegen
	    IF #stInOutHMIJam.#IncOne THEN
	        #stInOutHMIJam.#nIndex += 1;
	        IF #stInOutHMIJam.#nIndex > #stInOutHMIJam.#upperBound - 9 THEN
	            #stInOutHMIJam.#nIndex := #stInOutHMIJam.#upperBound - 9;
	            IF #stInOutHMIJam.nIndex <= 0 THEN
	                #stInOutHMIJam.nIndex := 1;
	            END_IF;
	        END_IF;

	        #nIdxMerker := #stInOutHMIJam.nIndex;

	        FOR #nIdx := 1 TO 10 DO
	            #stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
	            #nIdxMerker += 1;
	            IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
	                EXIT;
	            END_IF;
	        END_FOR;
	        #stInOutHMIJam.#IncOne := FALSE;
	    END_IF;

	    // Liste um fünf nach unten bewegen
	    IF #stInOutHMIJam.#IncFive THEN
	        #stInOutHMIJam.#nIndex += 5;
	        IF #stInOutHMIJam.#nIndex > #stInOutHMIJam.#upperBound - 9 THEN
	            #stInOutHMIJam.#nIndex := #stInOutHMIJam.#upperBound - 9;
	            IF #stInOutHMIJam.nIndex < 0 THEN
	                #stInOutHMIJam.nIndex := 1;
	            END_IF;
	        END_IF;

	        #nIdxMerker := #stInOutHMIJam.nIndex;

	        FOR #nIdx := 1 TO 10 DO
	            #stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
	            #nIdxMerker += 1;
	            IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
	                EXIT;
	            END_IF;
	        END_FOR;
	        #stInOutHMIJam.#IncFive := FALSE;
	    END_IF;

	    // Zum Listenanfang springen
	    IF #stInOutHMIJam.#ScrollStart THEN
	        #stInOutHMIJam.#nIndex := 1;

	        #nIdxMerker := #stInOutHMIJam.nIndex;

	        FOR #nIdx := 1 TO 10 DO
	            #stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
	            #nIdxMerker += 1;
	            IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
	                EXIT;
	            END_IF;
	        END_FOR;

	        #stInOutHMIJam.#ScrollStart := FALSE;
	    END_IF;
	    // Zum Listenende springen
	    IF #stInOutHMIJam.#ScrollEnd THEN
	        #stInOutHMIJam.#nIndex := #stInOutHMIJam.#upperBound - 9;
	        IF #stInOutHMIJam.nIndex < 0 THEN
	            #stInOutHMIJam.nIndex := 1;
	        END_IF;

	        #nIdxMerker := #stInOutHMIJam.nIndex;

	        FOR #nIdx := 1 TO 10 DO
	            #stInOutHMIJam.arJamList[#nIdx - 1] := #arInOutJam[#nIdxMerker];
	            #nIdxMerker += 1;
	            IF #nIdx >= #nUpperBound OR #nIdxMerker > #nUpperBound THEN
	                EXIT;
	            END_IF;
	        END_FOR;

	        #stInOutHMIJam.#ScrollEnd := FALSE;
	    END_IF;
	END_REGION

	REGION FC_CAR_MOVE

	    // "FC_CARR_MOVE"(nInCommand := #stHMIJam.stCarMove.nCommand,
	    //                nInJamNr := #nInJamNr,//braucht nicht von HMI zu kommen - #stHMIJam.stCarMove.nJamNr,
	    //                nInTarget := #stHMIJam.stCarMove.nTarget,
	    //                xInStart := #stHMIJam.stCarMove.xStart,
	    //                xOutError => #stHMIJam.stCarMove.xError);

	    #stInOutHMIJam.stCarMove.xStart := FALSE;

	END_REGION

	REGION HMI
	    IF #stInOutHMIData.stStatus.bByte.%X7 THEN //%X7: Manuelle Zielvergabe aktiviert
	        #arInOutJam[1].nDestination := #stInOutHMIData.stConfig.nCapacitySetHMI; //Sorgt dafür, dass Carrier ein festes Ziel bekommen
	    END_IF;
	END_REGION
END_FUNCTION_BLOCK

