
/** Returns the smaller of two integer values. */
int min (int a, int b);

/** Returns the smaller of two floating point values. */
float min (float a, float b);

/** Returns the larger of two integer values. */
int max (int a, int b);

/** Returns the larger of two floating point values. */
float max (float a, float b);

/** Constrains an integer value to keep it within a given range.
 
    @param lowerLimit           the minimum value to return
    @param upperLimit           the maximum value to return
    @param valueToConstrain     the value to try to return
 
    @returns    the closest value to valueToConstrain which lies between lowerLimit
                and upperLimit (inclusive)
*/
int clamp (int lowerLimit, int upperLimit, int valueToConstrain);

/** Constrains a floating point value to keep it within a given range.
 
    @param lowerLimit           the minimum value to return
    @param upperLimit           the maximum value to return
    @param valueToConstrain     the value to try to return
 
    @returns    the closest value to valueToConstrain which lies between lowerLimit
                and upperLimit (inclusive)
*/
float clamp (float lowerLimit, float upperLimit, float valueToConstrain);

/** Returns the absolute value of an integer value. */
int abs (int arg);

/** Returns the absolute value of a floating point value. */
float abs (float arg);

/** Remaps a value from a source range to a target range.
    
    @param value        the value within the source range to map
    @param sourceMin    the minimum value of the source range
    @param sourceMax    the maximum value of the source range
    @param destMin      the minumum value of the destination range
    @param destMax      the maximum value of the destination range
 
    @returns    the original value mapped to the destination range
*/
float map (float value, float sourceMin, float sourceMax, float destMin, float destMax);

/** Remaps a value from a source range to the range 0 - 1.0.
 
    @param value        the value within the source range to map
    @param sourceMin    the minimum value of the source range
    @param sourceMax    the maximum value of the source range
 
    @returns    the original value mapped to the range 0 - 1.0
*/
float map (float value, float sourceMin, float sourceMax);

/** Performs a modulo operation (can cope with the dividend being negative).
    The divisor must be greater than zero.
*/
int mod (int dividend, int divisor);

/** Returns a random floating-point number.

    @returns a random value in the range 0 (inclusive) to 1.0 (exclusive)
*/
float getRandomFloat();

/** Returns a random integer, limited to a given range.

    @returns a random integer between 0 (inclusive) and maxValue (exclusive).
*/
int getRandomInt (int maxValue)

/** Returns the number of milliseconds since a fixed event (usually system startup).
 
    This returns a monotonically increasing value which it unaffected by changes to the
    system clock. It should be accurate to within a few millisecseconds.
 */
int getMillisecondCounter();

/** Returns the current firmware version. */
int getFirmwareVersion();

/** Logs an integer value to the console. */
void log (int data);

/** Logs a hexadecimal value to the console. */
void logHex (int data);

/** Returns the length of time spent in the function call in milliseconds. */
int getTimeInCurrentFunctionCall();

/** Returns the battery level between 0 and 1.0. */
float getBatteryLevel();

/** Returns true if the battery is charging. */
bool isBatteryCharging();

/** Returns true if this block is directly connected to the application,
    as opposed to only being connected to a different block via a connection port.
*/
bool isMasterBlock();

/** Returns true if this block is directly connected to the host computer. */
bool isConnectedToHost();

/** Sets whether status overlays should be displayed. */
void setStatusOverlayActive (bool active);

/** Returns the number of blocks in the current topology. */
int getNumBlocksInTopology();

/** Returns the ID of the block at a given index in the topology. */
int getBlockIDForIndex (int index);

/** Returns the ID of the block connected to a specified port. */
int getBlockIDOnPort (int port);

/** Returns the port number that is connected to the master block. Returns 0xFF if there is no path. */
int getPortToMaster();

/** Returns the block type of the block with this ID. */
int getBlockTypeForID (int blockID);

/** Sends a message to the block with the specified ID. 
    This will be processed in the handleMessage() callback.
    
    @param blockID     the ID of the block to send this message to
    @param param1      the first chunk of data to send
    @param param2      the second chunk of data to send
    @param param3      the third chunk of data to send
*/
void sendMessageToBlock (int blockID, int param1, int param2, int param3);

/** Sends a message to the host. 
    To receive this the host will need to implement the Block::ProgramEventListener::handleProgramEvent() method.
    
    @param param1      the first chunk of data to send
    @param param2      the second chunk of data to send
    @param param3      the third chunk of data to send
*/
void sendMessageToHost (int param1, int param2, int param3);

/** Combines a set of 8-bit ARGB values into a 32-bit colour and returns the result. */
int makeARGB (int alpha, int red, int green, int blue);

/** Blends the overlaid ARGB colour onto the base one and returns the new colour. */
int blendARGB (int baseColour, int overlaidColour);

/** Sets a pixel to a specified colour with full alpha.
    
    @param rgb    the colour to use (0xff...)
    @param x      the x coordinate of the pixel to fill
    @param y      the y coordinate of the pixel to fill
*/
void fillPixel (int rgb, int x, int y);

/** Blends a the current pixel colour with a specified colour. 
   
    @param argb    the colour to use
    @param x       the x coordinate of the pixel to blend
    @param y       the y coordinate of the pixel to blend
*/
void blendPixel (int argb, int x, int y);

/** Fills a rectangle on the display with a specified colour. 
 
    @param rgb       the colour to use (0xff...)
    @param x         the x coordinate of the rectangle to draw
    @param y         the y coordinate of the rectangle to draw
    @param width     the width of the rectangle to draw
    @param height    the height of the rectangle to draw
*/
void fillRect (int rgb, int x, int y, int width, int height);

/** Blends a rectangle on the display with a specified colour. 
 
    @param argb      the colour to use
    @param x         the x coordinate of the rectangle to blend
    @param y         the y coordinate of the rectangle to blend
    @param width     the width of the rectangle to blend
    @param height    the height of the rectangle to blend
*/
void blendRect (int argb, int x, int y, int width, int height);

/** Draws a rectangle on the block display with four corner colours blended together. 
 
    @param colourNW    the colour to use in the north west corner of the rectangle
    @param colourNE    the colour to use in the north east corner of the rectangle
    @param colourSE    the colour to use in the south east corner of the rectangle
    @param colourSW    the colour to use in the south west corner of the rectangle
    @param x           the x coordinate of the rectangle
    @param y           the y coordinate of the rectangle
    @param width       the width of the rectangle
    @param height      the height of the rectangle
*/
void blendGradientRect (int colourNW, int colourNE, int colourSE, int colourSW, int x, int y, int width, int height);

/** Draws a pressure point at a given centre LED with a specified colour and pressure. 
 
    @param argb      the colour to use
    @param touchX    the x position of the touch
    @param touchY    the y position of the touch
    @param touchZ    the pressure value of the touch
*/
void addPressurePoint (int argb, float touchX, float touchY, float touchZ);

/** Draws the pressure map on the block display. */
void drawPressureMap();

/** Fades the pressure map on the block display. */
void fadePressureMap();

/** Draws a number on the block display.
 
    @param value     the number to draw between 0 and 99
    @param colour    the colour to use
    @param x         the x coordinate to use
    @param y         the y coordinate to use
*/
void drawNumber (int value, int colour, int x, int y);

/** Clears the display setting all the LEDs to black. */
void clearDisplay();

/** Clears the display setting all the LEDs to a specified colour. */
void clearDisplay (int rgb);

/** Sends a 1-byte short midi message. */
void sendMIDI (int byte0);

/** Sends a 2-byte short midi message. */
void sendMIDI (int byte0, int byte1);

/** Sends a 3-byte short midi message. */
void sendMIDI  (int byte0, int byte1, int byte2);

/** Sends a key-down message.
 
    @param channel      the midi channel, in the range 0 to 15
    @param noteNumber   the key number, in the range 0 to 127
    @param velocity     the velocity, in the range 0 to 127
*/
void sendNoteOn (int channel, int noteNumber, int velocity);

/** Sends a key-up message.
 
    @param channel      the midi channel, in the range 0 to 15
    @param noteNumber   the key number, in the range 0 to 127
    @param velocity     the velocity, in the range 0 to 127
*/
void sendNoteOff (int channel, int noteNumber, int velocity);

/** Sends an aftertouch message.
 
    @param channel              the midi channel, in the range 0 to 15
    @param noteNumber           the key number, in the range 0 to 127
    @param level                the amount of aftertouch, in the range 0 to 127
*/
void sendAftertouch (int channel, int noteNumber, int level);

/** Sends a controller message.
 
    @param channel          the midi channel, in the range 0 to 15
    @param controller       the type of controller
    @param value            the controller value
 */
void sendCC (int channel, int controller, int value);

/** Sends a pitch bend message.
 
    @param channel      the midi channel, in the range 0 to 15
    @param position     the wheel position, in the range 0 to 16383
*/
void sendPitchBend (int channel, int position);

/** Sends a channel-pressure change event.
 
    @param channel              the midi channel, in the range 0 to 15
    @param pressure             the pressure, in the range 0 to 127
*/
void sendChannelPressure (int channel, int pressure);

//==============================================================================
/**  
    Use this method to draw the display. 
    The Block will call this approximately 25 times per second.
*/
void repaint()

/** Called when a button is pushed.
 
    @param index    the index of the button that was pushed
*/
void handleButtonDown (int index);

/** Called when a button is released.
 
    @param index    the index of the button that was released
*/
void handleButtonUp (int index);

/** Called when a touch event starts.
 
    @param index    the touch index, which will stay constant for each finger as it is tracked
    @param x        the X position of this touch on the device, in logical units starting from 0 (left)
    @param y        the Y position of this touch on the device, in logical units starting from 0 (top)
    @param z        the current pressure of this touch, in the range 0.0 (no pressure) to 1.0 (very hard)
    @param vz       the rate at which pressure is currently changing, measured in units/second
 */
void touchStart (int index, float x, float y, float z, float vz);

/** Called when a touch event moves.
 
    @param index    the touch index, which will stay constant for each finger as it is tracked
    @param x        the X position of this touch on the device, in logical units starting from 0 (left)
    @param y        the Y position of this touch on the device, in logical units starting from 0 (top)
    @param z        the current pressure of this touch, in the range 0.0 (no pressure) to 1.0 (very hard)
    @param vz       the rate at which pressure is currently changing, measured in units/second
*/
void touchMove (int index, float x, float y, float z, float vz);

/** Called when a touch event ends.
 
    @param index    the touch index, which will stay constant for each finger as it is tracked
    @param x        the X position of this touch on the device, in logical units starting from 0 (left)
    @param y        the Y position of this touch on the device, in logical units starting from 0 (top)
    @param z        the current pressure of this touch, in the range 0.0 (no pressure) to 1.0 (very hard)
    @param vz       the rate at which pressure is currently changing, measured in units/second
*/
void touchEnd (int index, float x, float y, float z, float vz);

/** Called when a program is loaded onto the block and is about to start. Do any setup here. */
void initialise();

/** Called when a block receives a MIDI message. */
void handleMIDI (int byte0, int byte1, int byte2);

/** Called when a block receives a message.

    @see sendMessageToBlock
*/
void handleMessage (int param1, int param2, int param3);
