/*                                              -*- mode:C++; fill-column:100 -*-
  SFBPrint.h - Generalized print formatting routines
  Copyright (C) 2009 The Regents of the University of New Mexico.  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
  USA

  $Id$
*/

/**
  \file SFBPrint.h Support for basic formatted printing
  \author David H. Ackley.  
  \date (C) 2009 All rights reserved.
  \lgpl
 */
#ifndef SFBPRINT_H
#define SFBPRINT_H

#include "SFBConstants.h"       /* For FACE_COUNT */
#include "SFBAlarm.h"           /* For SFBAlarmIndexType */ 
#include "SFBReactor.h"         /* For PacketHandler, Body */ 
#include "SFBFrame.h"

/* The 'plain function' print methods dish to all reflex-controlled faces! */

extern void print(const char * str);            ///< \eq #facePrint(u8 face, const char * str)
                                                ///  with \c face set to #ALL_FACES.
extern void print(const u8 * str, u32 len);     ///< \eq #facePrint(u8 face, const u8 * str,u32 len) 
                                                ///  with \c face set to #ALL_FACES.
extern void print(int decimal);                 ///< \eq #facePrint(u8 face, int decimal) 
                                                ///  with \c face set to #ALL_FACES.
extern void print(unsigned int decimal);        ///< \eq #facePrint(u8 face, unsigned long decimal) 
                                                ///  with \c face set to #ALL_FACES.
extern void print(long decimal);                ///< \eq #facePrint(u8 face, long decimal) 
                                                ///  with \c face set to #ALL_FACES.
extern void print(unsigned long decimal);       ///< \eq #facePrint(u8 face, unsigned long decimal) 
                                                ///  with \c face set to #ALL_FACES.
extern void print(long decimal, int code);      ///< \eq #facePrint(u8 face, unsigned long decimal, int code)
                                                ///  with \c face set to #ALL_FACES.
extern void print(double val);                  ///< \eq #facePrint(u8 face, double val) 
                                                ///  with \c face set to #ALL_FACES.
extern void printFace();                        ///< \eq #facePrintFace(u8 face) 
                                                ///  with \c face set to #ALL_FACES.

extern void println();                          ///< \eq #facePrintln(u8 face) 
                                                ///  with \c face set to #ALL_FACES.
extern void println(const char * str);          ///< \eq #facePrintln(u8 face, const char * str)
                                                ///  with \c face set to #ALL_FACES.
extern void println(const u8 * str, u32 len);   ///< \eq #facePrintln(u8 face, const u8 * str,u32 len) 
                                                ///  with \c face set to #ALL_FACES.
extern void println(int decimal);               ///< \eq #facePrintln(u8 face, int decimal) 
                                                ///  with \c face set to #ALL_FACES.
extern void println(unsigned int decimal);      ///< \eq #facePrintln(u8 face, unsigned long decimal)
                                                ///  with \c face set to #ALL_FACES.
extern void println(long decimal);              ///< \eq #facePrintln(u8 face, long decimal) 
                                                ///  with \c face set to #ALL_FACES.
extern void println(unsigned long decimal);     ///< \eq #facePrint(u8 face, unsigned long decimal)  
                                                ///  with \c face set to #ALL_FACES.
extern void println(long decimal, int code);    ///< \eq #facePrintln(u8 face, unsigned long decimal, int code) 
                                                ///  with \c face set to #ALL_FACES.
extern void println(double val);                ///< \eq #facePrint(u8 face, double val) 
                                                ///  with \c face set to #ALL_FACES.
extern void printlnCheckByte();                 ///< \eq #facePrintlnCheckByte() 
                                                ///  with \c face set to #ALL_FACES.

extern void facePrint(u8 face, const char * str);
extern void facePrint(u8 face, const u8 * str, u32 len);
extern void facePrint(u8 face, int decimal); 
extern void facePrint(u8 face, unsigned int decimal);
extern void facePrint(u8 face, long decimal);
extern void facePrint(u8 face, unsigned long decimal);
//extern void facePrint(u8 face, long decimal, int code);
extern void facePrint(u8 face, unsigned long decimal, int code);
extern void facePrint(u8 face, double val);
extern void facePrint(u8 face, double val);
extern void facePrintFace(u8 face);

extern void facePrintln(u8 face); 
extern void facePrintln(u8 face, const char * str);        ///< \eq #facePrint(u8 face, const char * str) 
                                                           ///  followed by #facePrintln().
extern void facePrintln(u8 face, const u8 * str, u32 len); ///< \eq #facePrint(u8 face, const u8 * str,u32 len)
                                                           ///  followed by #facePrintln().
extern void facePrintln(u8 face, int decimal);             ///< \eq #facePrint(u8 face, int decimal) 
                                                           ///  followed by #facePrintln().
extern void facePrintln(u8 face, unsigned int decimal);    ///< \eq #facePrint(u8 face, unsigned int decimal) 
                                                           ///  followed by #facePrintln().
extern void facePrintln(u8 face, long decimal);            ///< \eq #facePrint(u8 face, long decimal) 
                                                           ///  followed by #facePrintln().
extern void facePrintln(u8 face, unsigned long decimal);   ///< \eq #facePrint(u8 face, unsigned long decimal)
                                                           ///  followed by #facePrintln().
extern void facePrintln(u8 face, unsigned long decimal, int code);
                                                           ///< \eq #facePrint(u8 face, unsigned long decimal, int code) 
                                                           ///  followed by #facePrintln().
extern void facePrintln(u8 face, double val);              ///< \eq #facePrint(u8 face, double val) 
                                                           ///  followed by #facePrintln().
extern void facePrintlnCheckByte(u8 face);

/**
 * A FacePrinter is capable of performing low-level printing operations to some assigned (physical
 * or 'virtual') face.
 */
struct FacePrinter {
  void (*print)(u8 face, u8 byte);  ///< Handler to print a single data byte, or 0 if undefined.
  void (*println)(u8 face);         ///< Handler to print a packet terminator, or 0 if undefined.
  void (*printFaceCode)(u8 face);   ///< Handler to print a single-byte representation of its face
                                    ///code, or 0 if undefined.
  const char * (*getFaceName)(u8 face); ///< Handler to return a zstring name of this FacePrinter,
                                        ///or 0 if undefined.
};

extern bool faceHasPrinter(u8 face);
extern bool faceFindFreeFace(u8 & foundFace);
extern void faceSetPrinter(u8 face, const FacePrinter * handler) ;
extern void faceUnsetPrinter(u8 face) ;

/* The one-time serial startup code */
extern void print_startup_initialization() ;

#endif  /* SFBPRINT_H */

