#ifndef UTIL_H
#define	UTIL_H
//misc mini-libs for items on the I2C bus

#define DOWN_BUTTON 0x1
#define UP_BUTTON 0x2
#define OK_BUTTON 0x4

extern const char arialFont[];  //in arial.c

char OLEDadd=0x3C;
char buttonAdd=0x38;  
char OLEDcol=0;
char OLEDpage=0;

char checkDevice(char a){
    I2C1.beginTransmission(a);
    if (I2C1.endTransmission()==0){
      return 1;
    }else{
      return 0;
    }
}

char getButtons(void){      //get state of buttons connected to PCF8574 on bus
  I2C1.beginTransmission(buttonAdd);
  I2C1.write(0xFF);     //leave IO floating
  I2C1.endTransmission();
  I2C1.requestFrom(buttonAdd,1);
  delay(1);
  if(I2C1.available()==0){
    return 0xFF;
  }else{
    return I2C1.read();
  }
}

void OLEDcmd(char c){
  I2C1.beginTransmission(OLEDadd);
  I2C1.write(0x80); //write cmd
  I2C1.write(c);    //cmd
  I2C1.endTransmission();
}

void OLEDdata(char c){
  I2C1.beginTransmission(OLEDadd);
  I2C1.write(0x40); //write data
  I2C1.write(c);    //data
  I2C1.endTransmission();
}

void OLEDsetpage(char p){
  OLEDcmd(0xB0 + (p&7));      //set page address    
}

void OLEDsetcolumn(unsigned char c){
  OLEDcmd(0x00 + (c & 0x0F));  //set column lower address
  OLEDcmd(0x10 + ((c>>4)&0x0F));   //set column higher address    
}

void OLEDclear(char c){
  for(OLEDpage=0;OLEDpage<8;OLEDpage++){
    OLEDsetpage(OLEDpage);
    OLEDsetcolumn(0);
    I2C1.beginTransmission(OLEDadd);
    I2C1.write(0x40); //write data
    for(OLEDcol=0;OLEDcol<128;OLEDcol++){
      I2C1.write(c);    //data
    }
    I2C1.endTransmission();
  }
  OLEDpage=0;
  OLEDcol=0;
}

void OLEDinit(void){
  OLEDcmd(0x20);  //set addressing mode
  OLEDcmd(0x02);  //set page addressing mode (SH1106 only supports page mode)
  OLEDcmd(0x8D);  //Charge pump setting
  OLEDcmd(0x14);  //Enable Charge pump
  //OLEDcmd(0xA1);  //column reverse
  OLEDcmd(0xA0);  //column normal
  //OLEDcmd(0xC8);  //row reverse
  OLEDcmd(0xC0);  //row normal
  OLEDcmd(0x40);  //display start 0
  OLEDcmd(0xD3);  //display offset
  OLEDcmd(0x00);  //is zero
  OLEDcmd(0xAF);  //display on
  OLEDcmd(0x81);  //brightness
  OLEDcmd(0xFF);  //=max
}

char get4Bits(char c){  //expand 4 bits over 8 bits
  char r=0;
  if(c&1){r=r|3;}
  if(c&2){r=r|12;}
  if(c&4){r=r|48;}
  if(c&8){r=r|192;}
  return r;
}

void OLEDchar(char c, const char* f){ //draw c at current col/page, increment col
  int w,h,c0,c1,i,j,p;
  w=f[0];
  h=f[1]/8; //font is formatted for 8-bit
  c0=f[2];
  c1=f[3]+c0;
  if(c<c0){return;}   //out of range
  if(c>c1){return;}   //out of range
  p=(c-c0)*w*h+4;
  for(j=0;j<h;j++){
    OLEDsetpage(OLEDpage+j*2);
    OLEDsetcolumn(OLEDcol);
    I2C1.beginTransmission(OLEDadd);
    I2C1.write(0x40); //write data
    for(i=0;i<w;i++){
      I2C1.write(get4Bits(f[p+i+j*w]));    //data
    }
    I2C1.endTransmission();
    OLEDsetpage(OLEDpage+j*2+1);
    OLEDsetcolumn(OLEDcol);
    I2C1.beginTransmission(OLEDadd);
    I2C1.write(0x40); //write data
    for(i=0;i<w;i++){
      I2C1.write(get4Bits(f[p+i+j*w]>>4));    //data
    }
    I2C1.endTransmission();    
  }
  OLEDcol=OLEDcol+w;
}

void OLEDcharArray(const char* c, const char* f){ //draw c at current col/page, increment col
    while(*c){
        OLEDchar(*c++,f);
    }
}

#endif	/* UTIL_H */