package com.softgames.farmninja;

/* FMNPlayScreen.java
*
* (c) Softgames Deutschland, - 2013
* Confidential and proprietary.
* 
* The Main Game Play Screen
*/

/**
 Projectile motion can be stated as the:

y = 1/2 (at^2) + v0 t + y0

Where,
y = height
t = time
a = acceleration of the projectile because of gravity
V0 = Initial velocity of the projectile
Y0 = Initial height of the projectile

min angle = 55
max-angle = 87
min velocity = 35
max velocity = ?
 */

import java.util.Random;
import java.util.Vector;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;

import javax.microedition.media.Player;
import javax.microedition.media.PlayerListener;

import com.kiwavi.mobileutils.MobileUtils;

class FMNPlayScreen extends GameCanvas implements Runnable, PlayerListener
{
  // connection to app
  FarmNinjaMidlet app;
  
  // main background, score indicator, lives indicator
  Image img_background, img_lifewhole, img_lifeempty, img_lives[] = new Image[3];
  int width, height;
  Font largeFont, mediumFont, smallFont;
  String txtScoreIndicator = "SCORE: ", txtHighScore = "HighScore:";
  
  // fruit images
  Image img_animfruit[], imgshadow;
  Vector fruitList = new Vector();
  int fruit_nums[] = {1,4,7,2,5,8,3,6,9};
  
  // cut and effects
  Image img_bgsplash[], img_dotssplash[], collideImage;
  int porigx, porigy, SWORD_CUT=0, FRUIT_SMASH=1, POISON_SPILL=2, BUZZER_SOUND=3;
  int drorigx, drorigy, drendx, drendy, cutdx, cutdy;
  boolean cutting = false, dragging = false;
  Vector bg_splashEffects = new Vector(), sp_splashEffects = new Vector();
  Player game_sounds[] = new Player[5];
  boolean touchscreen = false; // determine which line to draw
  RectI riFruits[];
  PointI cutPoints[];
  int drcutcount = 0, drlinecount = 0;
  Vector vctCutFruits = new Vector();
  
  // scoring
  int numfruits = 1, score = 0, cutcount = 0, combotimecount = 0, combocount;  
  int gamelives = 3;
  
  // Image imgComboCount[], imgPraiseCount[];
  int PRAISE_POINTS =1, PRAISE_IN_A_ROW=2, PRAISE_NICE =3, PRAISE_WOW=4,PRAISE_SLICER=5,PRAISE_AWESOME=6,PRAISE_GOD=7,PRAISE_FN=8;
  int praisecount = 0, praisetimecount = 0, praise_index=0;
  int slowmocount = 0, slowmotimecount = 0;
  String txtSlowMoText = "SLOW MOTION !", txtComboPoints="COMBO POINTS", txt_gametexts[] = {"COMBO", "POINTS", "IN A ROW !!", "NICE !", "WOW !", "SLICER !", "AWESOME !", "GOD !", "FARM NINJA !"};

  // timing and game end
  int time_fruitinterval = 3000, time_fruitintervalcum = 3200;
  int minveloc = 40, maxveloc = 0;
  double anglemin = 67, anglemax = 87;
  double fruit_fly_interval = 0.30;
  boolean endgame = false, pausegame = false, drawing = false; // check if game is ended
  int endgameoption = 0;
  String txtPlayAgain = "PLAY AGAIN", txtGotoMenu = "MAIN MENU", txtGameOver = "GAME OVER";
  
  // others
  Random globalRandom;

  FMNPlayScreen(FarmNinjaMidlet app)
  {
	super(false);
    setFullScreenMode(true);	
	this.app = app;
	
	largeFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_LARGE);
	mediumFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_MEDIUM);	
	smallFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_SMALL);
	
	System.gc();

	try {

	  // game texts
	  String gameTexts[] = app.gameText.getGameText(app.getLanguage());
	  txtScoreIndicator = gameTexts[9]; // "SCORE: "
	  txtHighScore = gameTexts[10]; // "HighScore:"
	  txtPlayAgain = gameTexts[13]; //  "PLAY AGAIN", 
	  txtGotoMenu = gameTexts[12]; //  "MAIN MENU", 
	  txtGameOver = gameTexts[11]; // "GAME OVER"
	  txtSlowMoText = gameTexts[0]; // "SLOW MOTION !", 
	  txtComboPoints = gameTexts[14]; // "COMBO POINTS"	
	  
	  txt_gametexts[0] = gameTexts[14]; // {"COMBO", "POINTS", "IN A ROW !!", "NICE !", "WOW !", "SLICER !", "AWESOME !", "GOD !", "FARM NINJA !"};
	  txt_gametexts[1] = gameTexts[8];
	  txt_gametexts[2] = gameTexts[7];
	  txt_gametexts[3] = gameTexts[1];
	  txt_gametexts[4] = gameTexts[2];
	  txt_gametexts[5] = gameTexts[3];
	  txt_gametexts[6] = gameTexts[4];
	  txt_gametexts[7] = gameTexts[5];
	  txt_gametexts[8] = gameTexts[6];
	  // 
      img_animfruit = app.gameAssets.img_animfruit;
	  
	  // load the score indicator and lives	  
	  img_background = app.imggeneralbg;


	  img_lifewhole = app.gameAssets.imgLives[0];
	  img_lifeempty = app.gameAssets.imgLives[1];
	  img_lives[0] = img_lifewhole;
	  img_lives[1] = img_lifewhole;
	  img_lives[2] = img_lifewhole;
			  
	  // the cut effect
      img_bgsplash = app.gameAssets.img_bgsplash;
      img_dotssplash = app.gameAssets.img_dotssplash;
      imgshadow = app.gameAssets.img_shadow;
	  
	  // end game options
	  if (app.soundon == true)
	  {
		game_sounds = app.gameAssets.game_sounds;
	  }  
	}
	catch (Exception ex)
	{
	  app.showMessage("Error at FMNPlayScreen.init() " + ex);
	}
	catch (OutOfMemoryError omex)
	{
	  app.showMessage("Out of memory Error at FMNPlayScreen.init() " + omex);
	}	
	
  }
   
 
  public void sizeChanged(int w, int h)
  {
	this.width = w;
	this.height = h;
	
	if (h > 800)
	{
	  maxveloc = 101;		
	}
	if (h <= 800)
	{
	  maxveloc = 83;
	}
	if (h <= 640)
	{
	  maxveloc = 74;	
	}
	if (h <= 400)
	{
	  maxveloc = 58;
	}
	if (h <= 320)
	{
	  maxveloc = 50;
	}
	if (h <= 240)
	{
	  maxveloc = 44;
	}
	
	img_background = MobileUtils.resizeImage(img_background, width, height);
	
  }
  
  public void keyPressed(int keyCode)
  {
	// the keys are interpreted differently when game is ended and 
    // game end screen is shown
	if (endgame == true)
	{
		
	  if (keyCode == -6)
	  {
		endgameoption = 0;
		doEndgameOption();
		return;
	  }
	  if (keyCode == -7)
	  {
		endgameoption = 1;
		app.gotoMainMenu();
		return;
	  }	  
		
	  int gameaction = getGameAction(keyCode);
	  
	  if (gameaction == Canvas.LEFT && endgameoption == 1)
	  {
		endgameoption = 0;
		repaint();
		return;
	  }
	  if (gameaction == Canvas.RIGHT && endgameoption == 0)
	  {
		endgameoption = 1;
		repaint();
		return;
	  }
	  if (gameaction == Canvas.FIRE)
	  {
		doEndgameOption();
		repaint();
		return;
	  }
	  repaint();
	  return;
	}
	
	if (keyCode == Canvas.KEY_NUM1)
	{
	  keyCut(1, null);
	  return;
	}
	if (keyCode == Canvas.KEY_NUM2)
	{
	  keyCut(2, null);
	  return;
	}
	if (keyCode == Canvas.KEY_NUM3)
	{
	  keyCut(3, null);
	  return;
	}
	if (keyCode == Canvas.KEY_NUM4)
	{
	  keyCut(4, null);
	  return;
	}
	if (keyCode == Canvas.KEY_NUM5)
	{
	  keyCut(5, null);
	  return;
	}
	if (keyCode == Canvas.KEY_NUM6)
	{
	  keyCut(6, null);
	  return;
	}
	if (keyCode == Canvas.KEY_NUM7)
	{
	  keyCut(7, null);
	  return;
	}
	if (keyCode == Canvas.KEY_NUM8)
	{
	  keyCut(8, null);
	  return;
	}	
	if (keyCode == Canvas.KEY_NUM9)
	{
	  keyCut(9, null);
	  return;
	}
	
  }
  
  void getNumFruits()
  {
	if (score > 500) 
	{
	  numfruits = 6;
	  return;
	}
	if (score > 200) 
	{
	  numfruits = 5;
	  return;
	}
	if (score > 100) 
	{
	  numfruits = 4;
	  return;
	}
	if (score > 20) 
	{
	  numfruits = 3;
	  return;
	}
	if (score > 10) 
	{
	  numfruits = 2;
	  return;
	}
	
	
  }
  
  void keyCut(int fruitnum, FMNFruitImage fruitimage[])
  {

	if (fruitimage == null)
	{
	  playSound(SWORD_CUT);
      cutting = true;
      Vector toCut = new Vector();

	  for (int i = 0; i < fruitList.size(); i++)
	  {

	    FMNFruitImage cfi = (FMNFruitImage)fruitList.elementAt(i);
        int cfirn = cfi.getRandNum();
        if (cfirn == fruitnum)
        {
          toCut.addElement(cfi);
        }
	  }
	  
	  FMNFruitImage allCut[] = new FMNFruitImage[toCut.size()];
	  toCut.copyInto(allCut);
	  keyCut(fruitnum, allCut);
	  return;

	}
	else {
      try {

    	for (int i = 0; i < fruitimage.length; i++)
    	{
          // System.out.println("Drag Cut number " + i);    		
    	  if (fruitimage[i] == null) { break; }
          if (fruitimage[i].isfull())
          {           	
       	    // getNumFruits();
       	    FMNFruitImage cfi = fruitimage[i];
      	    FMNFruitImage splits[] = cfi.splitFruit(); // etPosition(5, cfiy);
      	    if (splits != null)
      	    {
       	      fruitList.addElement(splits[0]);
        	  fruitList.addElement(splits[1]);
      	      // repaint();
      	      splits[0].doMove();
      	      splits[1].doMove();
  	          makeCut(cfi, splits[0], splits[1]);
      	    }
      	    else {
      	      // System.out.println("Splits are null ");
      	    }
      	      
      	    BGSplashEffects splashere = new BGSplashEffects(img_bgsplash[cfi.imgnum], img_bgsplash[cfi.imgnum].getWidth(), img_bgsplash[cfi.imgnum].getHeight(), app, height, bg_splashEffects);
      	    splashere.setPosition(fruitimage[i].getX(), fruitimage[i].getY());
      	    bg_splashEffects.addElement(splashere);

    	    SPSplashEffects splashdots = new SPSplashEffects(img_dotssplash[cfi.imgnum], img_dotssplash[cfi.imgnum].getWidth(), img_dotssplash[cfi.imgnum].getHeight(),this, sp_splashEffects);
    	    sp_splashEffects.addElement(splashdots);
    	    splashdots.setPosition(cfi.getX(), cfi.getY()-10);
    	    splashdots.setGravity(cfi.gravity);      	    
    	    fruitList.removeElement(cfi);
 	    playSound(FRUIT_SMASH);
          }
        }
    	score();
    	cutting = false;
    	repaint();
    	
      }
      catch (Exception ex)
      {
        System.out.println("Error at KEYCUT_DRAG.split() " + ex);
        cutting = false;
      }

	}
  }
  
  void score()
  {
	// cutCount -= 1; 
	if (endgame == true)
	{
	  return;
	}
	score += cutcount;

	if (cutcount >= 2)
	{
	  // show combo points
	  combotimecount = 50;
	  
	  // repaint();
	  // add combo points
	  score += cutcount;
	  combocount = cutcount;

	  if (slowmotimecount == 0)
	  {
	    slowmocount += cutcount;
	  }
	  else { slowmocount = 0; }
	  if (slowmocount >= 30)
	  {
		this.slowmotimecount = 50;
	  }
	  
	  cutcount = 0;	  
	}
  }
  
  void cutMushroom()
  {
	try {
	  if (app.soundon == true)
	  {
		endGame();		  
	    game_sounds[POISON_SPILL].addPlayerListener(this);
	    playSound(POISON_SPILL);
	  }
	  else 
	  {
		endGame();
	  }
	}
	catch (Exception ex)
	{
	  System.out.println(game_sounds[POISON_SPILL] + "Error at FMNPlayScreen.cutMushroom()" + ex);
	}
  }
  
  void loseFruit(FMNFruitImage lostfruit)
  {
	// this.fruitList.removeElement(lostfruit);
	praisecount = 0;
	combotimecount = 0;
	playSound(BUZZER_SOUND);
	reduceLives();
	fruitList.removeElement(lostfruit);
  }
  
  
  void reduceLives()
  {
	gamelives -= 1;
	if (gamelives <= 0) 
	{ 
	  // app.showMessage("Lives are gone. GAME OVER !!!");
	  this.endGame();
	}
  }
  
 
  boolean intersects(FMNFruitImage fruitimage, int x, int y)
  {
	if (fruitimage.full == false ) { return false; }
    int x1 = fruitimage.getX();
	int y1 = fruitimage.getY();
	int y2 = y1 + fruitimage.height;
	int x2 = x1 + fruitimage.width;
	  
	if (x >= x1 && x <= x2 && y >= y1 && y <= y2)
	{
	  return true;
	}
	else { return false; }
  }  
  
  void makeCut(FMNFruitImage original, FMNFruitImage fritop, FMNFruitImage fribot)
  {
	fritop.drorigx = fritop.getX()+5;
	fritop.drendx = fribot.getX()+fribot.getWidth()-5;
    
	fritop.drendy = fritop.getY()+5;
    fritop.drorigy = fribot.getY()+fribot.getHeight()-5;
    
	fritop.cutdx = fritop.drendx-fritop.drorigx;
	fritop.cutdy = fritop.drendy-fritop.drorigy;
	if (original.isMushroom()==false)
	{
	  cutcount += 1;
	  praisecount += 1;
	  if (praisecount == 10)
	  {
	    this.score+= 10;
		praisetimecount = 50;
		praise_index = PRAISE_NICE;
		// praisecount = 10;
	  }
	  if (praisecount == 25)
	  {
		score+= 10;
		praisetimecount = 50;
		praise_index = PRAISE_WOW;
		// praisecount = 25;
	  }
	  if (praisecount == 50)
	  {
		score+= 10;		  
		praisetimecount = 50;
		praise_index = PRAISE_SLICER;
		// praisecount = 50;
	  }
	  if (praisecount == 100)
	  {
		score+= 10;		  
		praisetimecount = 50;
		praise_index = PRAISE_AWESOME;
		// praisecount = 100;
	  }
	  if (praisecount == 200)
	  {
		score+= 10;		  
		praisetimecount = 50;
		praise_index = PRAISE_GOD;
		// praisecount = 200;
	  }
	  if (praisecount == 500)
	  {
		score+= 10;		  
		praisetimecount = 50;
		praise_index = PRAISE_FN;
		// praisecount = 500;
	  }	  
	}
  }  
  
  int getPraiseCount(int prindex)
  {
	int prct = 0;
    if (prindex == PRAISE_NICE)
    {
	  prct = 10;
    }
    if (prindex == PRAISE_WOW)
    {
	  prct = 25;
    }
    if (prindex == PRAISE_SLICER)
    {
	  prct = 50;
    }
    if (prindex == PRAISE_AWESOME)
    {
	  prct = 100;
    }
    if (prindex == PRAISE_GOD)
    {
	  prct = 200;
    }
    if (prindex == PRAISE_FN)
    {
	  prct = 500;
    }    
	return prct;
  }

  public void pointerPressed(int x, int y)
  {
	if (touchscreen == false) { touchscreen = true; }
	if (endgame == true)
	{
	  // System.out.println("Game is Over .. touch!!");
	  try
	  {
	  if (y > (height-(app.gameAssets.controlFont.getHeight()+5)) && x < width/3)
	  {
		endgameoption = 0;
		repaint();
		Thread.sleep(300);
		doEndgameOption();
		return;
	  }
	  if (y > (height-(app.gameAssets.controlFont.getHeight()+5)) && x >= (width*2)/3)
	  {
		endgameoption = 1;
		repaint();
		Thread.sleep(300);
		doEndgameOption();
		return;
	  }
	  }
	  catch (Exception ex)
	  {
		System.out.println("Error at PointerPressed():endGame " + ex);
	  }
	  return;
	}

	drorigx = x;
	drorigy = y;
	
  }
  
  public void pointerReleased(int x, int y)
  {
	drorigx = 0;
	drendx = 0;
	drorigy = 0;
	drendy = 0;
	dragging = false;
	// cutting = true;
	repaint();
	FMNFruitImage fruitImages[] = new FMNFruitImage[vctCutFruits.size()];
	// System.out.println("Number of fruits to cut after release is  " + fruitImages.length + "  " + vctCutFruits.size() + "  " + fruitList.size());
	vctCutFruits.copyInto(fruitImages);
	if (fruitImages.length >= 1)
	{
	  keyCut(0, fruitImages);
        }			
	drcutcount = 0;
    cutPoints = new PointI[1];
    PointI thisPoint = new PointI();
	thisPoint.xp = x;
	thisPoint.yp = y;
    cutPoints[0] = thisPoint;    
	vctCutFruits = new Vector();
	cutting = false;

	repaint();

  }
  
  public void pointerDragged(int x, int y)
  {
	try {
	  if (dragging == false)
	  {
	    drendx = x;
	    drendy = y;
	    dragging = true;
	    cutPoints = new PointI[1];
	    PointI thisPoint = new PointI();
	    thisPoint.xp = x;
	    thisPoint.yp = y;
	    cutPoints[0] = thisPoint;
	    if (drcutcount == 0) { drcutcount = 50; }
	    repaint();
	  }
	  else {
		  if (drcutcount < 50) { drcutcount = 50; }
	    // check if anything is cut
	    for (int i = 0; i < fruitList.size(); i++)
	    {
	      FMNFruitImage cfi = (FMNFruitImage)fruitList.elementAt(i);
	      if (intersects(cfi, x, y) && !vctCutFruits.contains(cfi))
	      {
	        vctCutFruits.addElement(cfi);
	      }
	    }

		PointI thisPoint = new PointI();
		thisPoint.xp = x;
		thisPoint.yp = y;
	    
	    if (cutPoints == null) {
   	      cutPoints = new PointI[1];
              cutPoints[0] = thisPoint; 
	    }  
	    	
	      PointI oldCutPoints[] = new PointI[cutPoints.length];
	      for (int i = 0; i < oldCutPoints.length; i++)
	      {
	        oldCutPoints[i] = cutPoints[i];
	      }
	      cutPoints = new PointI[1+cutPoints.length];
	      for (int i = 0; i < oldCutPoints.length; i++)
	      {
	        cutPoints[i] = oldCutPoints[i];	
	      }

  	      cutPoints[cutPoints.length-1] = thisPoint;
            }
	    repaint();
	 
	}
	catch (Exception ex)
	{
	  System.out.println("Error at FMNPlaySCreen.pointerDragged() " + ex + "  " + this.fruitList.size() + " CP " + cutPoints + " DRCC " + drcutcount);
	  
	}

  }  
  
  public void paint(Graphics g)
  {
	String allobjects = "";
	
	if (width == 0)
	{
	  sizeChanged(getWidth(), getHeight());
	  return;
	}
        drawing = true;
	try {
	  	  if (endgame == true)
		  {
		    int endy = (height-largeFont.getHeight())/2;
		    int endx = width/2;
		    g.drawImage(img_background, 0, 0, Graphics.TOP | Graphics.LEFT);

		    g.setColor(0xFFFFFF);
		    g.setFont(largeFont);
		    g.drawString(txtGameOver, endx, endy, Graphics.TOP | Graphics.HCENTER);	  
		    
		    // show the scores at the center of the screen
		    g.setColor(0xFFFFFF);
		    g.setFont(mediumFont);
		    endy += 5+largeFont.getHeight();
		    endx = (width-(mediumFont.stringWidth(txtScoreIndicator + " "+ score + " ")))/2;
		    g.drawString(txtScoreIndicator + " "+ score + " ", endx, endy, Graphics.TOP | Graphics.LEFT);

		    // draw the high scores
		    g.setColor(0xFF8000); // g.setColor(0xFFFFFF);
		    g.setFont(smallFont);	    
		    endx = (width-(smallFont.stringWidth(txtHighScore + "  " + app.highscore + " ")))/2;
		    endy += 3+mediumFont.getHeight();
		    g.drawString(txtHighScore + "  " + app.highscore + " ", endx, endy, Graphics.TOP | Graphics.LEFT);
		    
		    // show the upper scores at the status bar on top
			g.setColor(0); // xFF1C24);
			g.setFont(largeFont);	    
			g.drawString(txtScoreIndicator + " " + score, 3, 5, Graphics.TOP | Graphics.LEFT);
			g.setColor(0); // xCA6500);
			g.setFont(mediumFont);	    
			g.drawString(txtHighScore + " " + app.highscore, 3, largeFont.getHeight()+8, Graphics.TOP | Graphics.LEFT);
			g.setColor(0xFFFFFF);

		    // draw the lives
			int origin = width-((img_lifewhole.getWidth()*img_lives.length) + (5 * img_lives.length));
			for (int i = 0; i < img_lives.length; i++)
			{
			  if (i < (3-gamelives))
			  {
			    g.drawImage(this.img_lifeempty, origin+(i*img_lifeempty.getWidth())+(i*5), 5, Graphics.TOP | Graphics.LEFT);
			  }
			  else {
			    g.drawImage(img_lives[i], origin+(i*img_lifewhole.getWidth())+(i*5), 5, Graphics.TOP | Graphics.LEFT);	
			  }
			}

		    g.setColor(0xFFFFFF);
	        g.setFont(app.gameAssets.controlFont);
			
			// ask about main menu or play again 
			// g.drawString("EG " + endgameoption, width/2, height-10, Graphics.TOP | Graphics.LEFT);
			if (endgameoption == 0)
			{
			  g.setColor(app.gameAssets.ctrl_hl_color);			
			  g.drawString(txtPlayAgain, 5, height-5, Graphics.BOTTOM | Graphics.LEFT);
			  g.setColor(app.gameAssets.ctrl_normal_color);		  
			  g.drawString(txtGotoMenu, width-5, height-5, Graphics.BOTTOM | Graphics.RIGHT);
			}
			if (endgameoption == 1)
			{	
			  g.setColor(app.gameAssets.ctrl_normal_color);			
			  g.drawString(txtPlayAgain, 5, height-5, Graphics.BOTTOM | Graphics.LEFT);
			  g.setColor(app.gameAssets.ctrl_hl_color);
			  g.drawString(txtGotoMenu, width-5, height-5, Graphics.BOTTOM | Graphics.RIGHT);			
			}
		    return;
		  }  // END IF ENDGAME IS TRUE		


        g.drawImage(img_background, 0, 0, Graphics.TOP | Graphics.LEFT);
        g.setColor(0xFFFFFFFF);
        g.setFont(app.gameAssets.controlFont);
      
        // g.drawString(slowmotimecount + ":" + slowmocount, width/2, 5, Graphics.TOP | Graphics.HCENTER);
        // draw any splash backgrounds
        for (int i = 0; i < bg_splashEffects.size(); i++)
        {
          BGSplashEffects splashere = (BGSplashEffects)bg_splashEffects.elementAt(i);
          splashere.ticktock();
          splashere.paint(g);	
        }
      
        g.setColor(0xFFFFFF);
        try {
          // draw fruits
          for (int i = 0; i < fruitList.size(); i++)
          {
            FMNFruitImage cfi = (FMNFruitImage)fruitList.elementAt(i);
      
            g.setColor(0xFFFFFF);

            // draw the shadow        	
            g.drawImage(imgshadow, cfi.getX()+2, cfi.getY()+3, Graphics.TOP | Graphics.LEFT);
            cfi.paint(g);        
        
            if (cfi.isfull())
            {
              g.drawString(""+cfi.getRandNum(), cfi.getOutX(), cfi.getOutY(), Graphics.BOTTOM | Graphics.RIGHT);
            }
            else {       	
    	      if (cfi.hasline && cfi.isupper)
    	      {
    		    if (cutcount == 1)
    		    {
    		      cfi.cutcount = 1;
    		      cutcount = 0;
    		    }

    		    // draw the cut line
    		    if (touchscreen == false)
    		    {
    		      if (Math.abs(cfi.cutdy) >= Math.abs(cfi.cutdx))
    	          {
    	            for (int j = 0; j < 5; j++)
    	            {
    	    	      g.drawLine(cfi.drorigx+j, cfi.drorigy, cfi.drendx+j, cfi.drendy);
    	            }
    	          }
    	          else {
    	            for (int j = 0; j < 5; j++)
    	            {
    	      	      g.drawLine(cfi.drorigx, cfi.drorigy+j, cfi.drendx, cfi.drendy+j);
    	            }
    	          }
    		    }
    		    else {
    	    	  g.setColor(0xAAc0ffc0);    	  
    	    	  if (cfi.cutPoints != null)
    	    	  {
    	    	    for (int k = 0; k < cfi.cutPoints.length; k++)
    	    	    {
    	    		  if (k > 0) {
    	    		    for (int j = 0; j < 4; j++)
    	    		    {
    	    	          g.drawLine(cfi.cutPoints[k-1].xp+j, cfi.cutPoints[k-1].yp+j, cfi.cutPoints[k].xp+j, cfi.cutPoints[k].yp+j);
    	    		    }
    	    		  }
    	    	    }
    	    	  }
    		  }
    	      // g.drawImage(app.fmnGraphicText.getText("+1", FMNGraphicText.MEDIUM_YELLOW), cfi.drorigx, cfi.drorigy, Graphics.TOP | Graphics.LEFT);
    	    
    		  // Flash the +1 point score next to the fruit
    		  g.setColor(0xFF8000);
        	  if (cfi.cutcount == 1)
        	  {
        	    int xpos = cfi.drorigx;
        	    g.drawString("+1",  xpos , cfi.drorigy, Graphics.TOP | Graphics.LEFT);
        	  }
        	
    	    } // END IF DRAW UPPER HALF OF THE FRUIT
          } // END IF-ELSE DRAW HALF FRUIT

        } // END FOR LOOP DRAW ALL THE FRUITS
      } catch (Exception frex)
      {
    	System.out.println("Error at drawFruits " + frex);
      }
     
       g.setColor(0xAAc0ffc0);    	  
       if (cutPoints != null)
       {
      	 for (int i = 0; i < cutPoints.length; i++)
      	 {
      	   if (i > 0) {
      		 for (int j = 0; j < 4; j++)
      	     {
      	        g.drawLine(cutPoints[i-1].xp+j, cutPoints[i-1].yp+j, cutPoints[i].xp+j, cutPoints[i].yp+j);
      		 }
      	   }
      	 }
       } 
  	  

  	   allobjects = "SPL" + sp_splashEffects + " cut points " + cutPoints +  " GA " + app.gameAssets;  
  	   // draw combo scores
  	   if (combotimecount < 1200 && combotimecount > 0) 
  	   {
  		 g.setColor(app.gameAssets.prompt_color);
  		 g.setFont(app.gameAssets.controlFont);

  		 int xpos = (width-app.gameAssets.controlFont.stringWidth("+"+combocount + " " + txtComboPoints))/2;
  		 int nypos = ((height-app.gameAssets.controlFont.getHeight())/2)-15;
  		 g.drawString("+"+combocount + " " + txtComboPoints, xpos , nypos, Graphics.TOP | Graphics.LEFT);
  		
  	   }
    
  	  // draw praise scores
  	  if (praisetimecount < 1800 && praisetimecount > 0) 
  	  {
    	g.setColor(0X8000FF);
      	g.setFont(largeFont);  		  
  		int imgwid = 0;
  		imgwid += largeFont.stringWidth(txt_gametexts[praise_index]);
  		int xpos = (width-imgwid)/2;
  		
  		// draw the main text in one row
  		int oypos = 15+(height-largeFont.getHeight())/2;
  		g.drawString(txt_gametexts[praise_index], xpos , oypos, Graphics.TOP | Graphics.LEFT);

  		// draw the numbers in the row below
  		g.setColor(app.gameAssets.prompt_color);
  		g.setFont(app.gameAssets.controlFont);  		

  		int hypos = (oypos+5+largeFont.getHeight());
  		xpos = (width - app.gameAssets.controlFont.stringWidth(praisecount + " " + txt_gametexts[PRAISE_POINTS]))/2;
    	g.drawString(getPraiseCount(praise_index) + " " + txt_gametexts[PRAISE_POINTS], xpos , hypos, Graphics.TOP | Graphics.LEFT);
    	xpos = (width - app.gameAssets.controlFont.stringWidth(txt_gametexts[PRAISE_IN_A_ROW]))/2;
    	hypos = hypos + 5 + app.gameAssets.controlFont.getHeight();
    	g.drawString(txt_gametexts[PRAISE_IN_A_ROW], xpos , hypos, Graphics.TOP | Graphics.LEFT);

  	  }
      // draw any splash dots
      for (int i = 0; i < sp_splashEffects.size(); i++)
      {
        SPSplashEffects splashere = (SPSplashEffects)sp_splashEffects.elementAt(i);
        splashere.doMove();
        splashere.ticktock();
        splashere.paint(g);	
      }    
    
      // draw the score area
	  // show the upper scores at the status bar on top
	  g.setColor(0); // 0xFF1C24);
	  g.setFont(largeFont);	    
	  g.drawString(txtScoreIndicator + "  " + score, 3, 5, Graphics.TOP | Graphics.LEFT);
	  g.setColor(0); // xCA6500);
	  g.setFont(mediumFont);	    
	  g.drawString(txtHighScore + "  " + app.highscore, 3, largeFont.getHeight()+8, Graphics.TOP | Graphics.LEFT);
    
      // draw the lives
	  int origin = width-((img_lifewhole.getWidth()*img_lives.length) + (5 * img_lives.length));
	  for (int i = 0; i < img_lives.length; i++)
	  {
		if (i < (3-gamelives))
		{
	      g.drawImage(this.img_lifeempty, origin+(i*img_lifeempty.getWidth())+(i*5), 5, Graphics.TOP | Graphics.LEFT);
		}
		else {
		  g.drawImage(img_lives[i], origin+(i*img_lifewhole.getWidth())+(i*5), 5, Graphics.TOP | Graphics.LEFT);	
		}
	  }
	  
      if (this.slowmotimecount > 50 && this.slowmotimecount < 7000)
      {
    	g.setColor(0x0080C0);
    	g.setFont(largeFont);    	  
    	// draw the slow motion sign
    	g.drawString(txtSlowMoText, width/2, height-(largeFont.getHeight()+5), Graphics.TOP | Graphics.HCENTER);
      }


	}
	catch (Exception ex)
	{
	  System.out.println("Error at FMNPlayScreen.paint()" + ex + "  FruitListSize " + this.fruitList.size() + " Cut Points " + cutPoints + "  SPL = " + sp_splashEffects);
	}

    drawing = false;
  } 
  
  int[] rotateArray(int array[])
  {
    int firstnum = array[0];
    for (int i = 1; i < array.length; i++)
    {
      array[i-1] = array[i];
    }

    array[array.length-1] = firstnum;

    return array;
  }
  
  void makeFruit()
  {
	int chosen_fruit = -1;	
	getNumFruits();
	int velocity = 0;
	
    if (fruitList.size() == 0)
    {
      fruit_nums = rotateArray(fruit_nums);
    }	

	try {
	  Vector velocvec = new Vector();
	  Vector posvec = new Vector();
	  Random frRandom = new Random();
	  Random angRandom = new Random();
	  globalRandom = new Random();
	  for (int i = 0; i < numfruits; i++)
	  {
		
		chosen_fruit = Math.abs(frRandom.nextInt(img_animfruit.length));
	    // create a fruit
		int framewidth = img_animfruit[chosen_fruit].getWidth()/8;
		int frameheight = img_animfruit[chosen_fruit].getHeight()/3;

	    FMNFruitImage cfi = new FMNFruitImage(img_animfruit[chosen_fruit], framewidth, frameheight, this, true);
	   
	    cfi.imgnum = chosen_fruit;
	    if (chosen_fruit == 3) 
	    {    	
	      cfi.setMushroom(true); 
	    }
	    else { 
		  cfi.setMushroom(false);  
	    }
		
		int leftofrange = -10;
		int posx = getRandomInt(new Integer(width+20), posvec);
		posvec.addElement(new Integer(posx));
		posx += leftofrange;

		velocity = getRandomInt(new Integer(Math.abs(maxveloc-minveloc)), velocvec);
		velocvec.addElement(new Integer(velocity));
		velocity += minveloc;

		double angle = Math.toRadians((angRandom.nextDouble()*(anglemax-anglemin)) + anglemin);

	
	    // set its position and type (curve move or straight move)
	    cfi.setMotion(posx, (height-2), angle, velocity);
	    fruitList.addElement(cfi);

	  }
	  

	}
	catch (Exception ex)
	{
	  System.out.println(" Error at FMNPlayScreen.makeFruit() " + ex);
	}
  }
  
  void removeIntFromVector(int intvalue, Vector vct)
  {
	for (int i = 0; i < vct.size(); i++)
	{
	  Integer inint = (Integer)vct.elementAt(i);
	  if (inint.intValue() == intvalue) { vct.removeElementAt(i); }
	}
	
  }
  
  int getRandomInt(Integer max, Vector exclude)
  {
	  
	Integer myint = new Integer(0);
	try {
	myint = new Integer(globalRandom.nextInt(Math.abs(max.intValue())));
	int exclarray[] = new int[exclude.size()];
	
	for (int i = 0; i < exclarray.length; i++)
	{
	  Integer inint = (Integer)exclude.elementAt(i);		
	  exclarray[i] = inint.intValue();
	}
	
	
	
	for (int i = 0; i < exclarray.length; i++)
	{
	  if (myint.intValue() == exclarray[i])
	  {
		i = 0;
		myint = new Integer(globalRandom.nextInt(max.intValue()));
		continue;
	  }
	}
	
	}
	catch (Exception ex)
	{
	  System.out.println(" Error at getRandomInt() " + ex);
	}
	return myint.intValue();
  }
  
  public void run()
  {
	  
	while (endgame == false)
	{
	  try {
		  
		Thread.sleep(30);
		if (drawing == true) { continue; }
		if (endgame == true) { break; }

		if (pausegame == true)
		{
		  // repaint();
		  continue;	
		}
		if (slowmotimecount >= 7000)
		{
		  slowmotimecount = 0;
		  slowmocount = 0;
		  fruit_fly_interval = 0.32;
		}
		else if (slowmotimecount > 0 && slowmotimecount < 7000)
		{
		  slowmotimecount += 30;
		  fruit_fly_interval = 0.16;
		}		
		
		if (drcutcount >= 300)
		{

		    if (vctCutFruits != null && vctCutFruits.size() >= 1)
		    {
		      FMNFruitImage fruitImages[] = new FMNFruitImage[vctCutFruits.size()];
		      vctCutFruits.copyInto(fruitImages);
		      if (fruitImages.length >= 1)
		      {
		        keyCut(0, fruitImages);
		      }
			  vctCutFruits = new Vector();
	          cutPoints = null;
	          dragging = false;
		    }
        	cutPoints = null;
        	dragging = false;
      	    drcutcount = 0;

	
		  // cutPoints = null;
		  cutting = false;
          
		}
		else if (drcutcount > 0 && drcutcount < 350)
		{
		  drcutcount += 50;
		}
		
		if (combotimecount > 1200)
		{
		  combotimecount = 0;
	  	  combocount = 0;
		}
		else if (combotimecount > 0 && combotimecount < 1200)
		{
		  combotimecount += 50;
		}
		
		
		if (praisetimecount > 1800)
		{
		  praisetimecount = 0;
		  score += 10;
		}
		else if (praisetimecount > 0 && praisetimecount < 1800)
		{
		  praisetimecount += 50;
		}

  	          for (int i = 0; i < fruitList.size(); i++)
  	          {
  	            FMNFruitImage cfi = (FMNFruitImage)fruitList.elementAt(i);
  	            cfi.doMove();
                  }
	

	    repaint();
	    time_fruitintervalcum += 50;
  	    if (time_fruitintervalcum >= time_fruitinterval)
	    {
	      makeFruit();
	      time_fruitintervalcum = 0;
	    }
	  }
	  catch (Exception ex)
	  {
	    System.out.println("Error at PlayScreen.run() " + ex);
	  }
	  
	}
	
  }
  
  void endGame()
  {
	endgame = true;
	combotimecount = 0;
	praisecount = 0;
	app.highscore = Math.max(app.highscore, score);

	app.hdbrSettings.set("HIGH_SCORE", ""+app.highscore);
	app.hdbrSettings.persistData();

    fruitList = new Vector();

    repaint();
  }
  
  void doEndgameOption()
  {
	if (endgameoption == 1)
	{
	  app.gotoMainMenu();
	  return;
	}
	if (endgameoption == 0)
	{
	  app.gotoPlayScreen();
	  return;
	}	
  }

  public void playerUpdate(Player ply, String eventType, Object eventData) 
  {
	try {

	  if (ply == game_sounds[POISON_SPILL] && (eventType == PlayerListener.END_OF_MEDIA  || eventType.equalsIgnoreCase("endOfMedia")))
	  {
		endGame();
		return;
	  }
	}
	catch (Exception ex)
	{
	  System.out.println("Error at FMNPlayScreen.playerUpdate() " + ex);
	}
  }
  
  void playSound(final int soundindex)
  {
	/* Thread playerThread = new Thread(new Runnable()
	{
	  public void run()
	  {
		try {
	      Player plySound = game_sounds[soundindex];

	      if (plySound != null && app.soundon == true)
	      {
	        plySound.start();
	      }
		}
		catch (Exception ex)
		{
		  System.out.println("Error at PlayScreen.PlaySound(): " + soundindex + "  " + ex);
		}
		
	  }
	});
	playerThread.start(); */
		 
  }
}