/*****************************************************************************
 *  Module for Microchip Graphics Library
 *  GOL Layer 
 *  Round Dial
 *****************************************************************************
 * FileName:        RoundDial.h
 * Dependencies:    None 
 * Processor:       PIC24
 * Compiler:       	MPLAB C30 V3.00
 * Linker:          MPLAB LINK30
 * Company:         Microchip Technology Incorporated
 *
 * Software License Agreement
 *
 * Copyright © 2007 Microchip Technology Inc.  All rights reserved.
 * Microchip licenses to you the right to use, modify, copy and distribute
 * Software only when embedded on a Microchip microcontroller or digital
 * signal controller, which is integrated into your product or third party
 * product (pursuant to the sublicense terms in the accompanying license
 * agreement).  
 *
 * You should refer to the license agreement accompanying this Software
 * for additional information regarding your rights and obligations.
 *
 * SOFTWARE AND DOCUMENTATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY
 * OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
 * PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR
 * OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION,
 * BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT
 * DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL,
 * INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA,
 * COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY
 * CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
 * OR OTHER SIMILAR COSTS.
 *
 * Author               Date        Comment
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Paolo A. Tamayo		11/12/07	Version 1.0 release
 *****************************************************************************/

#ifndef _ROUNDDIAL_H
#define _ROUNDDIAL_H


/*********************************************************************
* Object States Definition: 
*********************************************************************/
#define RDIA_DISABLED    	0x0002  // Bit for disabled state.
#define RDIA_ROT_CW     	0x0004  // Bit for rotate clockwise state.
#define RDIA_ROT_CCW    	0x0008  // Bit for rotate counter clockwise state.
#define RDIA_DRAW        	0x4000  // Bit to indicate object must be redrawn.
#define RDIA_HIDE        	0x8000  // Bit to indicate object must be removed from screen.

/*********************************************************************
* Overview: Defines the parameters required for a dial Object.
* 			The curr_xPos, curr_yPos, new_xPos and new_yPos parameters
*			are internally generated to aid in the redrawing of the 
* 			dial. User must avoid modifying these values. 
*
*********************************************************************/
typedef struct {
	WORD			ID;				// A Unique id assigned for referencing.
	void           *pNxtObj;        // A pointer to the next object.
	GOL_OBJ_TYPE 	type;	        // Identifies the type of GOL object.
	WORD 	 		state;          // Dial states.
	SHORT           xCenter;		// x coordinate center position.
	SHORT           yCenter;		// y coordinate center position.
	SHORT           radius;			// Radius of the dial.
	SHORT           value;        	// Initial value of the dial.
	GOL_SCHEME     *pGolScheme;     // Style scheme used.
	WORD            max;    		// Maximum value of variable value (maximum = 65535).
    								// Minimum is always zero.
	WORD 			res;			// Resolution of movement.
	SHORT			curr_xPos;		// Current x position.
	SHORT			curr_yPos;		// Current y position.
	SHORT			new_xPos;		// New x position.
	SHORT			new_yPos;		// New y position.
} ROUNDDIAL;

/*********************************************************************
* Function: ROUNDDIAL  *RdiaCreate(	WORD ID, SHORT x, SHORT y, SHORT radius, 
*						WORD state, SHORT res, SHORT value, SHORT max, 
*						GOL_SCHEME *pScheme);				 
*
* Overview: This function creates a ROUNDDIAL object with the parameters given. 
*			It automatically attaches the new object into a global linked list of 
*			objects and returns the address of the object.
*
* PreCondition: none
*
* Input: ID - Unique user defined ID for the object instance.
*        x - Location of the center of the dial in the x coordinate.
*        y - Location of the center of the dial in the y coordinate.
* 		 radius - Defines the radius of the dial. 
*        state - Sets the initial state of the object.
*        res - Sets the resolution of the dial when rotating clockwise or
*			   counter clockwise.
*        value - Sets the initial value of the dial.
*        max - Sets the maximum value of the dial.
*        pScheme - Pointer to the style scheme used.
*
* Output: Returns the pointer to the object created.
*
* Example:
*   <PRE> 
*	GOL_SCHEME *pScheme;
*	ROUNDDIAL *pDial;
*	WORD state;
*	
*		pScheme = GOLCreateScheme();
*		state = RDIA_DRAW;
*
*		// creates a dial at (50,50) x,y location, with an initial value
*		// of 50, a resolution of 2 and maximum value of 100.
*		pDial = RdiaCreate(1,50,50,25,118,0, state, 2, 50, 100, pScheme);
*		// check if dial was created
*		if (pDial == NULL)		
*		   return 0;
*
*		return 1;
*	</PRE> 
*
* Side Effects: none
*
********************************************************************/
ROUNDDIAL  *RdiaCreate(	WORD ID, SHORT x, SHORT y, SHORT radius, 
						WORD state, SHORT res, SHORT value, SHORT max, 
						GOL_SCHEME *pScheme);				 

/*********************************************************************
* Function: RdiaTranslateMsg(ROUNDDIAL *pDia, GOL_MSG *pMsg)
*
* Overview: This function evaluates the message from a user if the 
*			message will affect the object or not. The table below enumerates the translated 
*			messages for each event of the touch screen and keyboard inputs.
*
*	<TABLE>
*    	Translated Message      Input Source  Events        Description
*     	#####################   ############  ######        ###########
*     	RD_MSG_CLOCKWISE        Touch Screen  EVENT_MOVE	If events occurs and the x,y position falls in the face of the Dial and moving in the clockwise rotation.
*		RD_MSG_CTR_CLOCKWISE    Touch Screen  EVENT_MOVE	If events occurs and the x,y position falls in the face of the Dial and moving in the counter clockwise rotation.     					      			   
*		OBJ_MSG_INVALID		    Any		      Any			If the message did not affect the object.							 
*	</TABLE>
*
* PreCondition: none
*
* Input: pDia  - The pointer to the object where the message will be
*				 evaluated to check if the message will affect the object.
*        pMsg  - Pointer to the message struct containing the message from 
*        		 the user interface.
*
* Output: Returns the translated message depending on the received GOL message:
*		  - RD_MSG_CLOCKWISE  Dial is moved in a clockwise direction.
*         - RD_MSG_CTR_CLOCKWISE  Dial is moved in a counter clockwise direction.
*         - OBJ_MSG_INVALID  Dial is not affected
*
* Example:
*   <PRE> 
*	void MyGOLMsg(GOL_MSG *pMsg){
*
*		OBJ_HEADER *pCurrentObj;
*		WORD objMsg;
*			
*		if(pMsg->event == EVENT_INVALID)
*			return;
*		pCurrentObj = GOLGetList();
*		
*		while(pCurrentObj != NULL){
*			// Process only ROUNDDIAL
*			if(!IsObjUpdated(pCurrentObj)){
*				switch(pCurrentObj->type){
*					case OBJ_ROUNDIAL:
*						objMsg = RdiaTranslateMsg((ROUNDDIAL*)pCurrentObj, pMsg);
*						if(objMsg == OBJ_MSG_INVALID)
*							break;
*						if(GOLMsgCallback(objMsg,pCurrentObj,pMsg))
*							RdiaMsgDefault(objMsg,(ROUNDDIAL*)pCurrentObj);
*						break;
*					default: break;	
*				}
*			}
*		}
*		pCurrentObj = pCurrentObj->pNxtObj;
*	}
*	</PRE> 
*
* Side Effects: none
*
********************************************************************/
WORD RdiaTranslateMsg(ROUNDDIAL *pDia, GOL_MSG *pMsg);

/*********************************************************************
* Function: RdiaMsgDefault(WORD translatedMsg, ROUNDDIAL *pDia, GOL_MSG* pMsg)
*
* Overview: This function performs the actual state change 
*			based on the translated message given.
*
* PreCondition: none
*
* Input: translatedMsg - The translated message
*        pDia          - The pointer to the object whose state will be modified
*        pMsg          - The pointer to the GOL message
*        
* Output: none
*
* Example:
*	See RdiaTranslateMsg() example.
*
* Side Effects: none
*
********************************************************************/
void  RdiaMsgDefault(WORD translatedMsg, ROUNDDIAL *pDia, GOL_MSG* pMsg);

/*********************************************************************
* Macros:  RdiaGetVal(pDia)
*
* Overview: Returns the current dial value. Value is always
*           in the 0-max range inclusive.
*
* PreCondition: none
*
* Input: pDia - Pointer to the object.
*
* Output: Returns the current value of the dial.
*
* Example:
*   <PRE> 
*	WORD currVal;
*	ROUNDDIAL *pDia;
*
*		// assuming pDia is initialized to an existing dial Object
*		currVal = RdiaGetVal(pDia);
*	</PRE> 
*
* Side Effects: none
*
********************************************************************/
#define RdiaGetVal(pDia)  	(pDia)->value

/*********************************************************************
* Macros:  RdiaSetVal(pDia, newVal)	
*
* Overview: Sets the value to the given new value. Value set must be in 0-max
*			range inclusive.
*
* PreCondition: none
*
* Input: pDia - Pointer to the object. 
*		 newVal - New dial value.
*
* Output: none
*
* Example:
*   <PRE> 
*	WORD updatedVal;
*	ROUNDDIAL *pDia;
*
*		// assuming pDia is initialized to an existing dial Object
*		// assume GetInput() is a function that retrieves source data
*		updatedVal = GetInput();
*		RdiaSetVal(pDia, updatedVal);
*	</PRE> 
*
* Side Effects: none
*
********************************************************************/
#define RdiaSetVal(pDia, newVal)	(pDia)->value = newVal

/*********************************************************************
* Macros:  RdiaIncVal(pDia)
*
* Overview: Used to directly increment the value. The delta
*           change used is the resolution setting (res).
*
* PreCondition: none
*
* Input: pDia - Pointer to the object.
*
* Output: none
*
* Example:
*   <PRE> 
*	WORD updatedVal, prevVal;
*	ROUNDDIAL *pDia;
*
*		// assuming pDia is initialized to an existing dial Object
*		// assume GetInput() is a function that retrieves source data
*		prevVal = RdiaGetVal(pDia);
*		updatedVal = GetInput();
*		if (updatedVal > prevVal)
*			RdiaIncVal(pDia);
*		if (updatedVal < prevVal)
*			RdiaDecVal(pDia);
*	</PRE> 
*
* Side Effects: none
*
********************************************************************/
#define RdiaIncVal(pDia)		RdiaSetVal(pDia, (pDia->val + pDia->res))

/*********************************************************************
* Macros:  RdiaDecVal(pDia)
*
* Overview: Used to directly decrement the value. The delta
*           change used is the resolution setting (res).
*
* PreCondition: none
*
* Input: pDia - Pointer to the object.
*
* Output: none
*
* Example:
*   Refer to RdiaIncVal() example.
*
* Side Effects: none
*
********************************************************************/
#define RdiaDecVal(pDia)		RdiaSetVal(pDia, (pDia->pos - pDia->res))

/*********************************************************************
* Function: RdiaDraw(ROUNDDIAL *pDia)
*
* Overview: This function renders the object on the screen using 
* 			the current parameter settings. Location of the object is 
*			determined by the center (x,y) postion and the radius parameters. 
*			The colors used are dependent on the state of the object. 
*			
*			When rendering objects of the same type, each object 
*			must be rendered completely before the rendering of the 
*			next object is started. This is to avoid incomplete 
*			object rendering.
*
* PreCondition: Object must be created before this function is called.
*
* Input: pDia - Pointer to the object 
*
* Output: Returns the status of the drawing
*		  - 1 - If the rendering was completed and 
*		  - 0 - If the rendering is not yet finished. 
*
* Side Effects: none
*
********************************************************************/
WORD RdiaDraw(ROUNDDIAL *pDia);

#endif // _ROUNDDIAL_H
