#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include <exec/exec.h>

#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <clib/muimaster_protos.h>

#include <libraries/mui.h>

#include <pragmas/muimaster_pragmas.h>

#include "I2C.h"

#ifndef MAKE_ID
#define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
#endif

extern int I2CStatus ;
extern char *I2CFehlerText[];

void CheckApplicationMessage( void ) ;

enum { EINS_ON=1, ZWEI_ON,  DREI_ON,  VIER_ON,  FUENF_ON,  SECHS_ON,  SIEBEN_ON,  ACHT_ON,
       EINS_OFF , ZWEI_OFF, DREI_OFF, VIER_OFF, FUENF_OFF, SECHS_OFF, SIEBEN_OFF, ACHT_OFF,
       AN, AUS, ADR } ;

char Description[] = "I²C-Demo";
char Version[]     = "$VER: I²C-Demo V1.0 (27.12.94)";
char Copyright[]   = "©1994 by Karsten Krauskopf";

struct Library *MUIMasterBase;

APTR  app,
      Main_Window;

APTR  Eins,Zwei,Drei,Vier,Fuenf,Sechs,Sieben,Acht,
      An, Aus, Adr;

ULONG signals ;

/*************************/
/* Init & Fail Functions */
/*************************/

static void 
fail( APTR app,char *str)
{
  Close_I2C() ;

  if( app ) MUI_DisposeObject( (Object *)app );

  if( MUIMasterBase ) CloseLibrary( MUIMasterBase ) ;
  if( str ) { puts(str); exit(20); }
  exit(0);
}

static void 
init(void)
{
 if( !( MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN ) ) )
   fail( NULL, "Failed to open "MUIMASTER_NAME"." ) ;
}

int 
main(int argc,char *argv[])
{
  int answer=0 ;
  int retcode = 0 ;

  init();

  app = ApplicationObject,
          MUIA_Application_Title      , "I²C-Demo",
          MUIA_Application_Version    , Version,
          MUIA_Application_Copyright  , Copyright,
          MUIA_Application_Author     , "Karsten Krauskopf",
          MUIA_Application_Description, Description,
          MUIA_Application_Base       , "I2CDemo",

          MUIA_Application_Window, Main_Window = WindowObject,
            MUIA_Window_Title, "",
            MUIA_Window_ID   , MAKE_ID('D','E','M','O'),
            WindowContents, VGroup,
              Child, VGroup, GroupFrameT("Relais"),
                Child, HGroup, MUIA_Group_SameWidth, TRUE,
                  Child, Eins   = TextObject,
                                             MUIA_Frame, MUIV_Frame_Button,
                                             MUIA_InputMode, MUIV_InputMode_Toggle,
                                             MUIA_Text_PreParse, "\33c",
                                             MUIA_Text_Contents, "1",
                                  End,
                  Child, Zwei   = TextObject,
                                             MUIA_Frame, MUIV_Frame_Button,
                                             MUIA_InputMode, MUIV_InputMode_Toggle,
                                             MUIA_Text_PreParse, "\33c",
                                             MUIA_Text_Contents, "2",
                                  End,
                  Child, Drei   = TextObject,
                                             MUIA_Frame, MUIV_Frame_Button,
                                             MUIA_InputMode, MUIV_InputMode_Toggle,
                                             MUIA_Text_PreParse, "\33c",
                                             MUIA_Text_Contents, "3",
                                  End,
                  Child, Vier   = TextObject,
                                             MUIA_Frame, MUIV_Frame_Button,
                                             MUIA_InputMode, MUIV_InputMode_Toggle,
                                             MUIA_Text_PreParse, "\33c",
                                             MUIA_Text_Contents, "4",
                                  End,
                  Child, Fuenf  = TextObject,
                                             MUIA_Frame, MUIV_Frame_Button,
                                             MUIA_InputMode, MUIV_InputMode_Toggle,
                                             MUIA_Text_PreParse, "\33c",
                                             MUIA_Text_Contents, "5",
                                  End,
                  Child, Sechs  = TextObject,
                                             MUIA_Frame, MUIV_Frame_Button,
                                             MUIA_InputMode, MUIV_InputMode_Toggle,
                                             MUIA_Text_PreParse, "\33c",
                                             MUIA_Text_Contents, "6",
                                  End,
                  Child, Sieben = TextObject,
                                             MUIA_Frame, MUIV_Frame_Button,
                                             MUIA_InputMode, MUIV_InputMode_Toggle,
                                             MUIA_Text_PreParse, "\33c",
                                             MUIA_Text_Contents, "7",
                                  End,
                  Child, Acht   = TextObject,
                                             MUIA_Frame, MUIV_Frame_Button,
                                             MUIA_InputMode, MUIV_InputMode_Toggle,
                                             MUIA_Text_PreParse, "\33c",
                                             MUIA_Text_Contents, "8",
                                  End,
                End,
              End,
              Child, HGroup, MUIA_Group_SameWidth, TRUE,
                Child, An  = SimpleButton( "Alle an" ),
                Child, Aus = SimpleButton( "Alle aus" ),
              End,
              Child, HGroup,
                Child, Label2("Baustein-Adresse (hex): 0x"),
                Child, Adr = StringObject,
                       StringFrame,
                       MUIA_String_Accept, "0123456879abcdefABCDEF",
                       MUIA_String_MaxLen, 3,
                End,
              End,
            End,
          End,
        End; /* ApplicationObject */

  if( !app )
    fail( app, "Failed to create Application." ) ;

  DoMethod( Main_Window,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);

  DoMethod( Eins,   MUIM_Notify, MUIA_Selected, TRUE,  app, 2, MUIM_Application_ReturnID, EINS_ON );
  DoMethod( Eins,   MUIM_Notify, MUIA_Selected, FALSE, app, 2, MUIM_Application_ReturnID, EINS_OFF );

  DoMethod( Zwei,   MUIM_Notify, MUIA_Selected, TRUE,  app, 2, MUIM_Application_ReturnID, ZWEI_ON );
  DoMethod( Zwei,   MUIM_Notify, MUIA_Selected, FALSE, app, 2, MUIM_Application_ReturnID, ZWEI_OFF );

  DoMethod( Drei,   MUIM_Notify, MUIA_Selected, TRUE,  app, 2, MUIM_Application_ReturnID, DREI_ON );
  DoMethod( Drei,   MUIM_Notify, MUIA_Selected, FALSE, app, 2, MUIM_Application_ReturnID, DREI_OFF );

  DoMethod( Vier,   MUIM_Notify, MUIA_Selected, TRUE,  app, 2, MUIM_Application_ReturnID, VIER_ON );
  DoMethod( Vier,   MUIM_Notify, MUIA_Selected, FALSE, app, 2, MUIM_Application_ReturnID, VIER_OFF );

  DoMethod( Fuenf,  MUIM_Notify, MUIA_Selected, TRUE,  app, 2, MUIM_Application_ReturnID, FUENF_ON );
  DoMethod( Fuenf,  MUIM_Notify, MUIA_Selected, FALSE, app, 2, MUIM_Application_ReturnID, FUENF_OFF );

  DoMethod( Sechs,  MUIM_Notify, MUIA_Selected, TRUE,  app, 2, MUIM_Application_ReturnID, SECHS_ON );
  DoMethod( Sechs,  MUIM_Notify, MUIA_Selected, FALSE, app, 2, MUIM_Application_ReturnID, SECHS_OFF );

  DoMethod( Sieben, MUIM_Notify, MUIA_Selected, TRUE,  app, 2, MUIM_Application_ReturnID, SIEBEN_ON );
  DoMethod( Sieben, MUIM_Notify, MUIA_Selected, FALSE, app, 2, MUIM_Application_ReturnID, SIEBEN_OFF );

  DoMethod( Acht,   MUIM_Notify, MUIA_Selected, TRUE,  app, 2, MUIM_Application_ReturnID, ACHT_ON );
  DoMethod( Acht,   MUIM_Notify, MUIA_Selected, FALSE, app, 2, MUIM_Application_ReturnID, ACHT_OFF );

  DoMethod( An,     MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, AN  );
  DoMethod( Aus,    MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, AUS );
  DoMethod( Adr,    MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ADR );

  do
   {
    char buf[200];

    answer=0 ;
    retcode = 0 ;

    if( (retcode = Open_I2C()) != 0 )
     {
      sprintf( buf, "\033c\nFehler %d aufgetreten:\n\n\"%s\"\n ", retcode, I2CFehlerText[I2CStatus] ) ;
      answer = MUI_Request( app, NULL, 0, "I²C-Bus Fehler", "*_Nochmal|_Abbruch", buf ) ;

      if( answer == 0 )
       fail( app, NULL );

      Close_I2C() ;
     }
   }
  while( answer == 1 ) ;

  set( Main_Window, MUIA_Window_Open, TRUE ) ;

  CheckApplicationMessage() ;

  fail( app, NULL ) ;
}

void
CheckApplicationMessage( void )
{
  BOOL   running = TRUE,
         NewValue = FALSE ;
  UBYTE  RelaisInfo[1];
  int    Adresse;
  char   buf[250];
  char  *buffer;

  RelaisInfo[0] = 0xff ; /* alle aus */


  Adresse = PCF8574A_base|0x0c ;

  while( running )
   {
    ULONG id = DoMethod( app,MUIM_Application_Input,&signals ) ;

    switch( id )
     {
      case EINS_ON:
                    RelaisInfo[0] &= ~0x01 ;
                    NewValue = TRUE ;
                    break ;
      case EINS_OFF:
                    RelaisInfo[0] |= 0x01 ;
                    NewValue = TRUE ;
                    break ;
      case ZWEI_ON:
                    RelaisInfo[0] &= ~0x02 ;
                    NewValue = TRUE ;
                    break ;
      case ZWEI_OFF:
                    RelaisInfo[0] |= 0x02 ;
                    NewValue = TRUE ;
                    break ;
      case DREI_ON:
                    RelaisInfo[0] &= ~0x04 ;
                    NewValue = TRUE ;
                    break ;
      case DREI_OFF:
                    RelaisInfo[0] |= 0x04 ;
                    NewValue = TRUE ;
                    break ;
      case VIER_ON:
                    RelaisInfo[0] &= ~0x08 ;
                    NewValue = TRUE ;
                    break ;
      case VIER_OFF:
                    RelaisInfo[0] |= 0x08 ;
                    NewValue = TRUE ;
                    break ;
      case FUENF_ON:
                    RelaisInfo[0] &= ~0x10 ;
                    NewValue = TRUE ;
                    break ;
      case FUENF_OFF:
                    RelaisInfo[0] |= 0x10 ;
                    NewValue = TRUE ;
                    break ;
      case SECHS_ON:
                    RelaisInfo[0] &= ~0x20 ;
                    NewValue = TRUE ;
                    break ;
      case SECHS_OFF:
                    RelaisInfo[0] |= 0x20 ;
                    NewValue = TRUE ;
                    break ;
      case SIEBEN_ON:
                    RelaisInfo[0] &= ~0x40 ;
                    NewValue = TRUE ;
                    break ;
      case SIEBEN_OFF:
                    RelaisInfo[0] |= 0x40 ;
                    NewValue = TRUE ;
                    break ;
      case ACHT_ON:
                    RelaisInfo[0] &= ~0x80 ;
                    NewValue = TRUE ;
                    break ;
      case ACHT_OFF:
                    RelaisInfo[0] |= 0x80 ;
                    NewValue = TRUE ;
                    break ;

      case AN:
                    RelaisInfo[0] = 0x00 ;
                    set( Eins,   MUIA_Selected, TRUE ) ;
                    set( Zwei,   MUIA_Selected, TRUE ) ;
                    set( Drei,   MUIA_Selected, TRUE ) ;
                    set( Vier,   MUIA_Selected, TRUE ) ;
                    set( Fuenf,  MUIA_Selected, TRUE ) ;
                    set( Sechs,  MUIA_Selected, TRUE ) ;
                    set( Sieben, MUIA_Selected, TRUE ) ;
                    set( Acht,   MUIA_Selected, TRUE ) ;
                    NewValue = TRUE ;
                    break ;

      case AUS:
                    RelaisInfo[0] = 0xff ;
                    set( Eins,   MUIA_Selected, FALSE ) ;
                    set( Zwei,   MUIA_Selected, FALSE ) ;
                    set( Drei,   MUIA_Selected, FALSE ) ;
                    set( Vier,   MUIA_Selected, FALSE ) ;
                    set( Fuenf,  MUIA_Selected, FALSE ) ;
                    set( Sechs,  MUIA_Selected, FALSE ) ;
                    set( Sieben, MUIA_Selected, FALSE ) ;
                    set( Acht,   MUIA_Selected, FALSE ) ;
                    NewValue = TRUE ;
                    break ;

      case ADR:
                    get( Adr, MUIA_String_Contents, &buffer ) ;
                    stch_l( buffer, (long*)&Adresse ) ;
                    break ;

      case MUIV_Application_ReturnID_Quit:
                    running = FALSE;
                    break;

      default:
                    break ;
     }

    if( NewValue )
     {
      Send_I2C( Adresse, 1, RelaisInfo ) ;
      NewValue = FALSE ;
      if( I2CStatus )
       {
        sprintf( buf, "\033c\nFehler %d vom 'i2c.device' aufgetreten:\n\n\"%s\"\n ", I2CStatus, I2CFehlerText[I2CStatus] ) ;
        MUI_Request( app, NULL, 0, "I²C-Bus Fehler", "*_Ok", buf ) ;
       }
     }

    if( running && signals ) 
      Wait( signals ) ;
   }
}


