/*
    Map of Pinheader:
    
    In:                     Out:
      8              3V3    1  2 GND
      7              SCK    3  4 MOSI
      6 CSx         MISO    5  6 CS1
      5 MISO         CS2    7  8 CS3
      4 MOSI         SCL    9 10 SDA
      3 SCK
      2 GND
      1 3V3
    
     
     */
    #ifndef PINHEADER_H_
    #define PINHEADER_H_
    
    #define Out01  2
    #define Out02  4
    #define Out03 18
    #define Out04 23
    #define Out05 19
    //RX2:
    #define Out06 16
    #define Out07  5
    //TX2:
    #define Out08 17
    #define Out09 22
    #define Out10 21
    
    #define txt_Out01 " 3V3 "
    #define txt_Out02 " GND "
    #define txt_Out03 " SCK "
    #define txt_Out04 " MOSI "
    #define txt_Out05 " MISO "
    #define txt_Out06 " CS1 "
    #define txt_Out07 " CS2 "
    #define txt_Out08 " CS3 "
    #define txt_Out09 " I2C_SCL "
    #define txt_Out10 " I2C_SDA "
    
    #define In1 13
    #define In2 12
    #define In3 14
    #define In4 27
    #define In5 33
    #define In6 32
    #define In7 35
    #define In8 34
    
    int GPIOfromInPin(int iPin){
      switch (iPin){
        case 1: return In1;
        case 2: return In2;
        case 3: return In3;
        case 4: return In4;
        case 5: return In5;
        case 6: return In6;
        case 7: return In7;
        case 8: return In8;
      }; // switch iPin
      return -1;
    }; //GPIOfromInPin
    
    struct _pinUsage{
      bool bInUse;
      char cUsedBy[80];
    };
    
    _pinUsage pinUsage[8];
    
    void resetPinUsage(){
      for (int n=0; n<8; n++){
        pinUsage[n].bInUse = false;
        pinUsage[n].cUsedBy[0] = 0x00;
      };//for
    }; // resetPinUsage
    
    
    void OutAllLowInput() {
      pinMode(Out01,OUTPUT); digitalWrite(Out01,LOW);
      pinMode(Out02,OUTPUT); digitalWrite(Out02,LOW);
      pinMode(Out03,OUTPUT); digitalWrite(Out03,LOW);
      pinMode(Out04,OUTPUT); digitalWrite(Out04,LOW);
      pinMode(Out05,OUTPUT); digitalWrite(Out05,LOW);
      pinMode(Out06,OUTPUT); digitalWrite(Out06,LOW);
      pinMode(Out07,OUTPUT); digitalWrite(Out07,LOW);
      pinMode(Out08,OUTPUT); digitalWrite(Out08,LOW);
      pinMode(Out09,OUTPUT); digitalWrite(Out09,LOW);
      pinMode(Out10,OUTPUT); digitalWrite(Out10,LOW);
      delayMicroseconds(10);
      pinMode(Out02,INPUT);
      pinMode(Out02,INPUT);
      pinMode(Out03,INPUT);
      pinMode(Out04,INPUT);
      pinMode(Out05,INPUT);
      pinMode(Out06,INPUT);
      pinMode(Out07,INPUT);
      pinMode(Out08,INPUT);
      pinMode(Out09,INPUT);
      pinMode(Out10,INPUT);
    };
    
    void OutAllHigh(){
      pinMode(Out01,OUTPUT); digitalWrite(Out01,HIGH);
      pinMode(Out02,OUTPUT); digitalWrite(Out02,HIGH);
      pinMode(Out03,OUTPUT); digitalWrite(Out03,HIGH);
      pinMode(Out04,OUTPUT); digitalWrite(Out04,HIGH);
      pinMode(Out05,OUTPUT); digitalWrite(Out05,HIGH);
      pinMode(Out06,OUTPUT); digitalWrite(Out06,HIGH);
      pinMode(Out07,OUTPUT); digitalWrite(Out07,HIGH);
      pinMode(Out08,OUTPUT); digitalWrite(Out08,HIGH);
      pinMode(Out09,OUTPUT); digitalWrite(Out09,HIGH);
      pinMode(Out10,OUTPUT); digitalWrite(Out10,HIGH);
    };
    
    void SetGpioHigh(int iGPIO){
      pinMode(iGPIO,OUTPUT);
      digitalWrite(iGPIO,HIGH);
    }
    
    void SetGpioLow(int iGPIO){
      pinMode(iGPIO,OUTPUT);
      digitalWrite(iGPIO,LOW);
    }
    
    void checkUsedPins(){
      resetPinUsage();
      OutAllLowInput();
      OutAllHigh();
      delay(10);
      if (digitalRead(In1) == HIGH) pinUsage[0].bInUse = true;
      if (digitalRead(In2) == HIGH) pinUsage[1].bInUse = true;
      if (digitalRead(In3) == HIGH) pinUsage[2].bInUse = true;
      if (digitalRead(In4) == HIGH) pinUsage[3].bInUse = true;
      if (digitalRead(In5) == HIGH) pinUsage[4].bInUse = true;
      if (digitalRead(In6) == HIGH) pinUsage[5].bInUse = true;
      if (digitalRead(In7) == HIGH) pinUsage[6].bInUse = true;
      if (digitalRead(In8) == HIGH) pinUsage[7].bInUse = true;
    };
    
    bool testPinConnection(int iIn, int iOut){
      int testA, testB;
      OutAllLowInput();
      SetGpioHigh(iOut);
      testA = digitalRead(iIn);
      SetGpioLow(iOut);
      testB = digitalRead(iIn);
    
      if ( (testA==HIGH) && (testB==LOW) ) return true;
      return false;
    }
    
    // iInPin = 1 to 8
    void checkMap(int iInPin){
      if (iInPin > 8) return;
      if (iInPin < 1) return;
      int iGPIO = GPIOfromInPin(iInPin);
      if (iGPIO < 0) return;
    
      int n=iInPin-1;
      if (testPinConnection(iGPIO, Out01)) strcat(pinUsage[n].cUsedBy,txt_Out01);
      if (testPinConnection(iGPIO, Out02)) strcat(pinUsage[n].cUsedBy,txt_Out02);
      if (testPinConnection(iGPIO, Out03)) strcat(pinUsage[n].cUsedBy,txt_Out03);
      if (testPinConnection(iGPIO, Out04)) strcat(pinUsage[n].cUsedBy,txt_Out04);
      if (testPinConnection(iGPIO, Out05)) strcat(pinUsage[n].cUsedBy,txt_Out05);
      if (testPinConnection(iGPIO, Out06)) strcat(pinUsage[n].cUsedBy,txt_Out06);
      if (testPinConnection(iGPIO, Out07)) strcat(pinUsage[n].cUsedBy,txt_Out07);
      if (testPinConnection(iGPIO, Out08)) strcat(pinUsage[n].cUsedBy,txt_Out08);
      if (testPinConnection(iGPIO, Out09)) strcat(pinUsage[n].cUsedBy,txt_Out09);
      if (testPinConnection(iGPIO, Out10)) strcat(pinUsage[n].cUsedBy,txt_Out10);
      //OutAllLowInput(); SetGpioHigh(Out10);
      //if (digitalRead(iGPIO) == HIGH) strcat(pinUsage[n].cUsedBy,txt_Out10);
    }
    
    void runTest(){
      resetPinUsage();
      checkUsedPins();
      for (int n=1; n<=8; n++){
        if (pinUsage[n-1].bInUse == true) checkMap(n);
      }; // for
    }; // runTest
    
    #endif //PINHEADER_H_