#ifndef MAIN_H_
#define _MAIN_H

#include "global.h"

/** 
  *Creates a new config object. 
  */
Config *newConfig();

/** 
 * Deletes a config object.
 *
 * @param conf The conf object.
 */
void deleteConfig(Config *conf);

/** 
 * Reads next configuration.
 *
 * @param confFile The configuration file stream to read from.
 * @param rc Returncode: 0 on success, 1 on error.
 * @return The next configuration entry.
 */
Config *nextConfig(FILE *confFile, int *rc);

/**
 * Spawns the slaves.
 *
 * @param confFile Configuration file stream.
 * @return 0 on success, 1 on error.
 */
int spawnSlaves(FILE *confFile);

/**
 * Kills all slaves.
 */
void killSlaves();

/**
 * Finds the next idle slave.  A slave is idle iff slave status == SSIdle.
 *
 * @param pos The position to start the search from; 
 *            may be -1 if it doesn't matter.
 * @return slave number of idle slave, or -1 if none found.
 */
int nextIdleSlave(int pos);

/**
 * Finds the slave number for the given id.
 *
 * @param tid Task id of slave.
 * @return The slave number, or -1 if not found.
 */
int findSlave(int tid);

/**
 * Sends a complex number to the slave.
 * The given info is stored, so we will know for what pixel the slave did
 * return the result.
 * Expected answer: rceivePix()
 *
 * @param slave Slave number
 * @param c Number to send
 * @return Result of pvm_send; that is 0 on success, <0 on error.
 */
int sendPix(int slave, Compix c);

/**
 * Receives the corresponding iteration value from any slave.
 * This will also write the pixel to the image.
 *
 * @return Slave number we got the return from
 */
int receivePix();

/**
 * Sends a quit command to the slave.
 * Expected answer: receiveStat()
 *
 * @param slave Slave number.
 * @return Result of pvm_send; that is - on success, <0 on error.
 */
int sendQuit(int slave);

/**
 * Receives the utilization statistics from any slave.
 *
 * @return Slave number we got the statistics from.
 */
int receiveStat();

/**
 * Prints out the utilization statistics.
 */
void printutil();

/**
 * Creates the colormap.
 * A colormap contains one entry for each possible iteration value.
 */
void createCmap();

/**
 * Sets the value of a pixel.  Does nothing if pixel is not in image.
 *
 * @param p Pixel to set.
 * @param r Red color value.
 * @param g Green color value.
 * @param b Blue color value.
 * @see #setPixWithCmap
 */
void setPix(Coord p, unsigned char r, unsigned char g, unsigned char b);

/**
 * Sets the value of a pixel, depending on the color map.
 * Does nothing if pixel is not in image.
 *
 * @param p Pixel to set.
 * @param cmapIndex index in colormap to take color from.
 * @see #setPixWithCmap
 */
void setPixWithCmap(Coord p, int cmapIndex);

/**
 * Cleans up the process, kills all slaves and terminates the program
 * with the returncode.
 *
 * @param rc Returncode to terminate with.
 */
void bailOut(int rc);

/**
 * Main.
 * Paramters are: Configuration filename, xmin, xmax, ymin, ymax, maxiter.
 * See code or additional documentation for how it works.
 *
 * @param argc Argument counter
 * @param argv Arguments
 * @return rc
 */
int main(int argc, char *argv[]);

/**
 * The name of the config file.
 */
extern char *configFilename;

/**
 * Maximum number of iterations.
 */
extern int maxiter;

/**
 * Image is calculated for (xmin,ymin) to (xmax,ymax).
 */
extern float xmin, xmax, ymin, ymax;

/**
 * Task ids.
 */
extern int *tids;

/**
 * Slave status.
 */
extern SlaveStat *slaveStats;

/**
 * Current slave computation.
 */
extern Compix *slaveComp;

/**
 * Slave utilization statistics.
 */
extern Utilization *slaveUtil;

/**
 * Number of slaves. Also the length of tids, slaveStats, slaveComp and slaveUtil.
 */
extern int tids_len;

/**
 * Resolution of image.
 */
extern int xres, yres;

/**
 * The color map.
 */
extern unsigned char *cmap;

/**
 * The image.
 */
extern unsigned char *image;

#endif
