		//---------Shake Parameters start ---------------
		var MIN_CHANGES_XY = 2 ;
		var THRESHOLD_XY = 2 ;
		var LOWER_THRESHOLD_XY = 1 ;
		var STABLE_TIME_THRESHOLD_XY = 300 ;
		var THRESHOLD_XY_Z = 1 ;
		
		var MIN_CHANGES_Z = 3 ;
		var THRESHOLD_Z = 4 ;
		var LOWER_THRESHOLD_Z = 1 ;
		var STABLE_TIME_THRESHOLD_Z = 300 ;
		
		var ALPHA = 0.8 ;
		var FREQUENCY  = 100 ;
		var MAX_PAUSE_BETWEEN_CHANGES = 800 ;
		
		var timeOfFirstChange = 0 ;
		var timeOfLastChange = 0 ;
		var changeCount = 0 ;
		var lastX = 0 ;
		var lastY = 0 ;
		var lastZ = 0 ;
		
		var GestureDirection = 'none' ;
		var is_gesture_ending = false ;
		var gesture_end_start_time = 0 ;
		var gesture_start = false ;
		var currGesture = 'none' ;
		
		var acceleration_WatchID = null;
		var orientation_WatchID = null ;
		
		//----- variables for IOS to use device api html5 ----
		var acceleration_timer = null ;
		var orientation_timer = null ;
		var GlobalcurrAcceleration = {x : 0 , y:0 , z:9.8 , timestamp : 0} ;
		var GlobalcurrHeading = {magneticHeading : 0 } ;
		var CPPG_Gesture_isRunningInIOS = false ;
		//----- variables for IOS to use device api html5 end----
		
		//----------Shake Parameters end ------------------
		
		
		//-------orientation paramters start -----------------
		var ORI_FREQUENCY = 100 ;
		var ORI_MIN_ANGLE_COUNT_FOR_DIRECTION = 1 ;
		var ORI_MIN_CHANGE = 5 ;
		var ORI_MIN_SAMP_FOR_STABLE_ANGLE = 3;
		var ORI_VARIANCE_THRESHOLD = 5 ;
		
		var start_angle = 0 ;
		var should_start_angle_count = false ;
		var angle_count = 0 ;
		
		var last_stable_angle = 0 ;
		var stable_angle_arr = new Array() ;
		
		//--------orientation parameters end ------------------
		
		var gravity = {x : 0 , y : 0 , z: 9.8 } ;
		var previousReading = { x : null , y : null , z : null } ;
		
		document.body.onload = CPPGGesture_onBodyLoad();
		
		
		function CPPGGesture_onBodyLoad() {
			if(navigator.userAgent.match(/(iPhone|iPad|iPod)/i))
			{
				CPPG_Gesture_isRunningInIOS = true ;
			}
			if(CPPG_Gesture_isRunningInIOS)
			{
				var date  = new Date() ;
				GlobalcurrAcceleration.timestamp = date.getTime();
			}
			if (typeof navigator.device == "undefined"){
				document.addEventListener("deviceready", CPPGGesture_onDeviceReady, false);
			}
			else
			{
				CPPGGesture_onDeviceReady() ;
			}
		}

		// Cordova is ready
		//
		function CPPGGesture_onDeviceReady() {
			CPPGGesture_startWatch();
			CPPGGesture_startCompassWatch() ;
			document.addEventListener("pause" , CPPGGesture_onPause , false ) ;
			document.addEventListener("resume" , CPPGGesture_onResume , false ) ;
		}
		
		function CPPGGesture_onPause()
		{
			if(CPPG_Gesture_isRunningInIOS)
			{
				if( acceleration_timer != null )
				{
					clearInterval(acceleration_timer);
				}
				if( orientation_timer != null )
				{
					clearInterval(orientation_timer);
				}
				acceleration_timer = null ;
				orientation_timer = null ;
				GlobalcurrAcceleration = {x : 0 , y:0 , z:9.8 ,timestamp : 0} ;
				GlobalcurrHeading = {magneticHeading : 0 } ;
				// remove event listeners for html5 events 
				try{
					window.removeEventListener('devicemotion', CPPGGesture_deviceMotionHandler, false);
					window.removeEventListener('deviceorientation', CPPGGesture_deviceOrientHandler, false);
				}catch(e){}
			}
			else
			{
				if( acceleration_WatchID != null )
				{
					navigator.accelerometer.clearWatch( acceleration_WatchID );
				}
				if( orientation_WatchID != null )
				{
					navigator.compass.clearWatch( orientation_WatchID );
				}
				acceleration_WatchID = null ;
				orientation_WatchID = null ;
			}
			CPPGGesture_resetParameters();
			gravity = {x : 0 , y : 0 , z: 9.8 } ;
			previousReading = { x : null , y : null , z : null } ;
			CPPGGesture_resetAnglesForPauseEvent();
		}
		
		function CPPGGesture_onResume()
		{
			if(CPPG_Gesture_isRunningInIOS)
			{
				var date  = new Date() ;
				GlobalcurrAcceleration = {x : 0 , y:0 , z:9.8  } ;
				GlobalcurrAcceleration.timestamp = date.getTime();
				GlobalcurrHeading = {magneticHeading : 0 } ;
			}
			CPPGGesture_startWatch();
			CPPGGesture_startCompassWatch() ;
		}
			
		function CPPGGesture_startWatch() 
		{	
			if(CPPG_Gesture_isRunningInIOS)
			{
				if (window.DeviceMotionEvent) {
					console.log("DeviceOrientation is supported");
					window.addEventListener('devicemotion', CPPGGesture_deviceMotionHandler, false);
					acceleration_timer = setInterval(CPPGGesture_accelerationIntervalHandler,FREQUENCY);
				}
				else
				{
				}
			}
			else
			{
					acceleration_WatchID = navigator.accelerometer.watchAcceleration( CPPGGesture_onSuccess , CPPGGesture_onError, { frequency: FREQUENCY });
			}
		}
		
		function CPPGGesture_deviceMotionHandler(eventData) {
			var accg = eventData.accelerationIncludingGravity ;
			GlobalcurrAcceleration.x = accg.x ;
			GlobalcurrAcceleration.y = accg.y ;
			GlobalcurrAcceleration.z = accg.z ;
		}
		
		function CPPGGesture_accelerationIntervalHandler() 
		{
			var date = new Date();
			GlobalcurrAcceleration.timestamp = date.getTime();
			CPPGGesture_onSuccess(GlobalcurrAcceleration);
		
		}
				
		function CPPGGesture_onSuccess(acceleration)
		{
			var linear_acceleration = {} ;
			
			gravity.x = ALPHA * gravity.x + (1 - ALPHA) * acceleration.x ;
			gravity.y = ALPHA * gravity.y + (1 - ALPHA) * acceleration.y ;
			gravity.z = ALPHA * gravity.z + (1 - ALPHA) * acceleration.z ;
		  
			linear_acceleration.x = acceleration.x - gravity.x;
			linear_acceleration.y = acceleration.y - gravity.y;
			linear_acceleration.z = acceleration.z - gravity.z;
			linear_acceleration.timestamp = acceleration.timestamp ;
	
			if(gesture_start)
			{
				CPPGGesture_handleAlreadyStartedGesture(linear_acceleration);
			}
			else 
			{
			  if(changeCount != 0 )
			  {
					if(Math.abs( acceleration.timestamp - timeOfLastChange ) >= MAX_PAUSE_BETWEEN_CHANGES) 
					{
						CPPGGesture_resetParameters() ;
						CPPGGesture_resetAngles() ;
					}
			  }
			  CPPGGesture_handleGestureNotYetStarted(linear_acceleration , acceleration );  
			  
			} 
			
		
			previousReading = {
				x: linear_acceleration.x,
				y: linear_acceleration.y,
				z: linear_acceleration.z
			}
		
		}
		
		function CPPGGesture_shaken( gestureType , gestureDirection )
		{
			if( gestureType === 'XY')
			{
				if( gestureDirection === 'right')
				{
					cpCmndNextSlide = true ;
					cpCmndPause = true ;
				}
				else if( gestureDirection === 'left' )
				{
					cpCmndPreviousSlide = true ;
					cpCmndPause = true ;
				}
			}
			else if( gestureType === 'Z')
			{
				if(cpCmndPause)
				{
					cpCmndResume = true ;
				}
				else
				{
					cpCmndPause = true ;
				}
			}
		}
				// Error
		function CPPGGesture_onError() {
		}
		
		function CPPGGesture_handleAlreadyStartedGesture(acceleration) 
		{
			var currMagnitude ;
			if(currGesture === 'XY')
			{
				currMagnitude =  Math.sqrt((acceleration.x*acceleration.x) + (acceleration.y*acceleration.y) ) ; 
				if(currMagnitude < LOWER_THRESHOLD_XY ) 
				{
					if(is_gesture_ending)
					{	
						if(Math.abs(acceleration.timestamp - gesture_end_start_time) >= STABLE_TIME_THRESHOLD_XY )
						{	
							if( Math.abs(angle_count) >= ORI_MIN_ANGLE_COUNT_FOR_DIRECTION )
							{
								if(angle_count > 0 )
								{
									GestureDirection = 'right' ;
									CPPGGesture_shaken('XY','right');
								}
								else if(angle_count < 0) // a small value of threshold can be used instead of 0 
								{
									GestureDirection = 'left' ;
									CPPGGesture_shaken('XY','left');
								}
							}
							CPPGGesture_resetParameters() ;
							CPPGGesture_resetAngles() ;
						}							
					}
					else
					{
						is_gesture_ending = true ;
						gesture_end_start_time = acceleration.timestamp ;
					}
				}
				else
				{
					is_gesture_ending = false  ;
					gesture_end_start_time = 0 ;						
				}
			
			}
			else if(currGesture === 'Z') 
			{
				currMagnitude = Math.sqrt( (acceleration.z*acceleration.z) ) ; 
				if(currMagnitude < LOWER_THRESHOLD_Z ) 
				{
					if(is_gesture_ending)
					{	
						if(Math.abs(acceleration.timestamp - gesture_end_start_time) >= STABLE_TIME_THRESHOLD_Z )
						{	
							CPPGGesture_shaken('Z','none');
							CPPGGesture_resetParameters() ;
						}							
					}
					else
					{
						is_gesture_ending = true ;
						gesture_end_start_time = acceleration.timestamp ;
					}
				}
				else
				{
					is_gesture_ending = false  ;
					gesture_end_start_time = 0 ;						
				}
			}
			
		}
		
		function CPPGGesture_handleGestureNotYetStarted( acceleration , origAcceleration ) 
		{
			var changeInMagnitude_XY = Math.abs( acceleration.x + acceleration.y - lastX - lastY) ; 
			var changeInMagnitude_Z = Math.abs(  acceleration.z - lastZ) ;
			
			var changeInMagnitude_XY_Z = Math.abs ( acceleration.z - lastZ ) ;
			
			if( currGesture === 'none')
			{
				
				if( changeInMagnitude_XY > THRESHOLD_XY  && changeInMagnitude_XY_Z<=THRESHOLD_XY_Z)
				{
					CPPGGesture_handleChange(acceleration , 'XY') ;
				}
				else if( changeInMagnitude_Z > THRESHOLD_Z )
				{
					CPPGGesture_handleChange(acceleration , 'Z') ;
				}
			}
			
			else if( currGesture === 'XY') 
			{
				if( changeInMagnitude_XY > THRESHOLD_XY  )
				{
					CPPGGesture_handleChange(acceleration , 'XY') ;
				}	
			}
			
			else if( currGesture === 'Z') 
			{
				if( changeInMagnitude_Z > THRESHOLD_Z )
				{
					CPPGGesture_handleChange(acceleration , 'Z') ;
				}
			
			}
				  
				  
		}
		
		function CPPGGesture_handleChange( acceleration , gestureType ) 
		{
			currGesture = gestureType ;
			if( gestureType === 'XY')
			{
				if( timeOfFirstChange == 0 )
				{
					start_angle =  last_stable_angle ; // a condition if this is valid or not shuld be added //curr_average_angle ;
					angle_count = 0 ;
					should_start_angle_count = true ;
					timeOfFirstChange = acceleration.timestamp ;
					timeOfLastChange = acceleration.timestamp ;
				}
				CPPGGesture_onChangeDetected(acceleration , gestureType) ;
			
			}
			
			else if( gestureType === 'Z') 
			{
				if( timeOfFirstChange == 0 )
				{
					timeOfFirstChange = acceleration.timestamp ;
					timeOfLastChange = acceleration.timestamp ;				
				}
				
				CPPGGesture_onChangeDetected(acceleration , gestureType ) ;
			
			}
		}
		
		function CPPGGesture_onChangeDetected( accl , gestureType) {
			var currTime = accl.timestamp ;
			var ChangeAfter = currTime -  timeOfLastChange ;
			if(ChangeAfter < MAX_PAUSE_BETWEEN_CHANGES) 
			{
				if(gestureType === 'XY')
				{
					lastX = accl.x ;
					lastY = accl.y ;
					
					changeCount ++ ;
					timeOfLastChange = currTime ;
					
					if(changeCount >= MIN_CHANGES_XY)
					{
							gesture_start = true ;

					}
				}
				else if( gestureType === 'Z')
				{
					
					lastZ = accl.z ;
				
					changeCount ++ ;
					timeOfLastChange = currTime ;
					
					if(changeCount >= MIN_CHANGES_Z)
					{
						gesture_start = true ;										
					}
				}
			}
		
		}
		
		function CPPGGesture_resetParameters() 
		{
		
			lastX = 0 ;
			lastY = 0 ;
			lastZ = 0 ;
			GestureDirection = 'none' ;
			
			changeCount = 0  ;
			timeOfFirstChange = 0 ;
			timeOfLastChange = 0 ;
			
			gesture_start = false ;
			is_gesture_ending = false ;
			gesture_end_start_time = 0 ;
			
			currGesture = 'none' ;
		}
		
		//----------orientation functions start ------------
		
		function CPPGGesture_startCompassWatch() 
		{
			if(CPPG_Gesture_isRunningInIOS)
			{
				if (window.DeviceOrientationEvent) {
					console.log("DeviceOrientation is supported");

					window.addEventListener('deviceorientation', CPPGGesture_deviceOrientHandler, false);
					orientation_timer = setInterval(CPPGGesture_orientationIntervalHandler,ORI_FREQUENCY);
				}
				else
				{
				}
			}
			else
			{
				var options = { frequency: ORI_FREQUENCY };
				orientation_WatchID = navigator.compass.watchHeading(CPPGGesture_onCompassSuccess, CPPGGesture_onCompassError, options);	
			}
		}
		
		function CPPGGesture_deviceOrientHandler(eventData) {
			var heading = eventData.alpha ;
			GlobalcurrHeading.magneticHeading = heading ;
		}
		
		function CPPGGesture_orientationIntervalHandler() 
		{
			CPPGGesture_onCompassSuccess(GlobalcurrHeading);
		
		}
		
		function CPPGGesture_onCompassSuccess(heading) 
		{
			var currHeading = heading.magneticHeading ;
			CPPGGesture_updateStableAngle(currHeading) ;
			if(should_start_angle_count)
			{
				var diffAngle = currHeading-start_angle ; 
				if( Math.abs(diffAngle) >= ORI_MIN_CHANGE )
				{
					if( ( (diffAngle >= 0 )&& (diffAngle < 180 ) ) || ( (diffAngle >= -360 ) && (diffAngle < -180 ) ) )
					{
						if(CPPG_Gesture_isRunningInIOS)
						{
							angle_count -- ;
						}
						else
						{
							angle_count ++ ;
						}
					}
					else if( ( (diffAngle >= 180 )&& (diffAngle < 360 ) ) || ( (diffAngle >= -180 ) && (diffAngle < 0 ) ) )
					{
						if(CPPG_Gesture_isRunningInIOS)
						{
							angle_count ++ ;
						}
						else
						{
							angle_count -- ;
						}
					}
				}
			}
		}
		
		function CPPGGesture_onCompassError(compassError)
		{
			
		}
		
		function CPPGGesture_updateStableAngle( currHeading ) 
		{		
			if(stable_angle_arr.length == ORI_MIN_SAMP_FOR_STABLE_ANGLE)
			{
				stable_angle_arr.shift() ;
				stable_angle_arr.push(currHeading);
			}
			else if(stable_angle_arr.length < ORI_MIN_SAMP_FOR_STABLE_ANGLE)
			{
				stable_angle_arr.push(currHeading); 
			}
			if(stable_angle_arr.length == ORI_MIN_SAMP_FOR_STABLE_ANGLE)
			{
				var stable_angle_mean = 0 ;
				for( var i=0 ; i< stable_angle_arr.length ; i++)
				{
					stable_angle_mean += stable_angle_arr[i] ;
				}
							
				stable_angle_mean = stable_angle_mean / stable_angle_arr.length ;
				
				var stable_angle_variance = 0 ;
				for( i =0 ; i< stable_angle_arr.length ; i++)
				{
					stable_angle_variance += Math.pow( (stable_angle_arr[i] - stable_angle_mean) , 2) ;
				}
				stable_angle_variance = stable_angle_variance / stable_angle_arr.length ;
				
				if( stable_angle_variance < ORI_VARIANCE_THRESHOLD )
				{
					last_stable_angle = stable_angle_mean ;
				}
			}
		}
		
		function CPPGGesture_resetAngles() 
		{
			startAngle = 0 ;
			should_start_angle_count = false ;
			angle_count = 0 ;
		}
		
		function CPPGGesture_resetAnglesForPauseEvent()
		{
			startAngle = 0 ;
			should_start_angle_count = false ;
			angle_count = 0 ;
			last_stable_angle = 0 ;
			stable_angle_arr.splice( 0 , stable_angle_arr.length );
		}
		
		//-----------orientation functions end --------------------