/*
  Copyright (C) 2003  Taiga Yonekura, taiga@col.hi-ho.ne.jp

  For more information about this appliation please look at:
   http://www.pat.hi-ho.ne.jp/kyonekura

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/
#include <math.h>
#include <stdlib.h>

#include "fish.h"
#include "config.h"

#define SLOW_SPEED (rand() % EASY_FISH_SPEED_MAX)+EASY_FISH_SPEED_MIN
#define FAST_SPEED (rand() % HARD_FISH_SPEED_MAX)+HARD_FISH_SPEED_MIN

CFish::CFish(int scx,int scy,int x,int y, PIXMAP *img)
{
	int i;

	CFishInit(scx,scy,x,y,img);

	//init rad table
	for( i = 0; i < 24; ++i ) m_radTable[i]=3.14*(double)i/12;

	//set parameter 
	randset();
	
	setVisible(true);

}
void CFish::CFishInit(int scx,int scy,int x,int y,PIXMAP *img)
{
	  m_screenHeight = scy;
	  m_screenWidth = scx;
	  m_xsize = x;
	  m_ysize = y;
      
	  m_fishBMP = img;

}
CFish::~CFish()
{


}

int CFish::makerad()
{
	return (rand() % 24);
}
//
// set fish image list
//
void CFish::setImageList(PIXMAP *img)
{
  m_fishBMP = img;
}
//
// set way
//
void CFish::setWay(int i)
{
	m_way = i;
	m_rad = m_radTable[i];
}
//
// set position of fish
//
void CFish::randset()
{
	setPos(rand() % 500,rand() % 400);
	m_real_x = (double)(m_x0 = getPosX());
	m_real_y = (double)(m_y0 = getPosY());
	setWay(makerad());
	setVisible(true);
	m_speed = 6.0;
}

void CFish::draw(PAINTER* painter)
{
	PIXMAP *imgBMP;

	if(!getVisible()) return;

	switch( m_way ){
		case 0:case 1:case 23:
			// right
			imgBMP = &m_fishBMP[3];
			break;
		case 2:case 3:case 4:
			// slant right down
			imgBMP = &m_fishBMP[6];
			break;
		case 5:case 6:case 7:
			// down
			imgBMP = &m_fishBMP[1];
			break;
		case 8:case 9:case 10:
			// slant left down
			imgBMP = &m_fishBMP[7];
			break;
		case 11:case 12:case 13:
			// left
			imgBMP = &m_fishBMP[2];
			break;
		case 14:case 15:case 16:
			// slant left up
			imgBMP = &m_fishBMP[5];
			break;
		case 17:case 18:case 19:
			// up
			imgBMP = &m_fishBMP[0];
			break;
		default:
			// slant right up
			imgBMP = &m_fishBMP[4];
			break;
	}

	painter->drawPixmap( m_pos_x, m_pos_y, *imgBMP );


}
//
// If x postion of fish is out of visible area,return false .
//
bool CFish::cheak_x(int x)
{
   if( x < 0 || x > m_screenWidth - m_xsize ) return false;
   return true;
}
//
// If y postion of fish is out of visible area,return false . 
//
bool CFish::cheak_y(int y)
{
   if( y < 0 || y > m_screenHeight - m_ysize ) return false;
   return true;
}

void CFish::set_real_y_slow()
{
	  m_real_y += m_speed * sin(m_rad);
	  if(!cheak_y((int)m_real_y)){
		  if(m_real_y < 0.0) m_real_y = 0.0; 
		  else m_real_y = (double)(m_screenHeight - m_ysize);
		  setWay(makerad());
		  m_speed = SLOW_SPEED;
	  }
	  if((int)((100 - 0 + 1) * rand() + 0) % 15 == 0) setWay(makerad());

}

void CFish::set_real_y()
{
	  m_real_y += m_speed * sin(m_rad);
	  if(!cheak_y((int)m_real_y)){
		  if(m_real_y < 0.0) m_real_y = 0.0; 
		  else m_real_y = (double)(m_screenHeight - m_ysize);
		  setWay(makerad());
		  m_speed = FAST_SPEED;
	  }
	  if((int)((100 - 0 + 1) * rand() + 0) % 15 == 0) setWay(makerad());

}

void CFish::set_real_x_slow()
{
	  m_real_x += m_speed * cos(m_rad);
	  if(!cheak_x((int)m_real_x) ){
		  if(m_real_x < 0.0) m_real_x = 0.0; 
		  else m_real_x = (double)(m_screenWidth - m_xsize);
		  setWay(makerad());
		  m_speed = SLOW_SPEED;
	  }

	  if((int)((100 - 0 + 1) * rand() + 0) % 8 == 0) setWay(makerad());
}

void CFish::set_real_x()
{
	  m_real_x += m_speed * cos(m_rad);

	  if(!cheak_x((int)m_real_x) ){
		  if(m_real_x < 0.0) m_real_x = 0.0; 
		  else m_real_x = (double)(m_screenWidth - m_xsize);
		  setWay(makerad());
		  m_speed = FAST_SPEED;
	  }

	  if((int)((100 - 0 + 1) * rand() + 0) % 8 == 0) setWay( makerad() );
}

void CFish::movefast()
{
	set_real_x();
	set_real_y();
	setPos((int)m_real_x,(int)m_real_y);
}

void CFish::moveslow()
{
	set_real_x_slow();
	set_real_y_slow();
	setPos((int)m_real_x,(int)m_real_y);
}

void CFish::initSpeed( CFish::LEVEL level )
{
  switch( level ){

  case HARD:
    m_speed = FAST_SPEED;
    break;

  case EASY:
    m_speed = SLOW_SPEED;
    break;

  }

}
//
//
//
void CFish::setHitArea(CFish::AREA_TYPE type, CHitArea *Area[],int AreaCount)
{

  CHitArea* pHitArea = new CHitArea[AreaCount];
  m_HitArea[type] = pHitArea;

  for(int i = 0; i < AreaCount; i++){
    m_HitArea[type][i] = *Area[i];
  }

  m_HitAreaCount[type] = AreaCount;

  

}
int CFish::checkUpperNet( CHitArea *Area )
{

  CHitArea* pHitArea;
  int Areacount;

  switch( m_way ){

  case 0:case 1:case 23:
    // right
    pHitArea = m_HitArea[ RIGHT ];
    Areacount = m_HitAreaCount[ RIGHT ];
    break;

  case 2:case 3:case 4:
    // slant right down
    pHitArea = m_HitArea[ RIGHT_DOWN ];
    Areacount = m_HitAreaCount[ RIGHT_DOWN ];			
    break;

  case 5:case 6:case 7:
    // down
    pHitArea = m_HitArea[ DOWN ];
    Areacount = m_HitAreaCount[ DOWN ];			
    break;

  case 8:case 9:case 10:
    // slant left down
    pHitArea = m_HitArea[ LEFT_DOWN ];
    Areacount = m_HitAreaCount[ LEFT_DOWN ];			
    break;
		
  case 11:case 12:case 13:
    // left
    pHitArea = m_HitArea[ LEFT ];
    Areacount = m_HitAreaCount[ LEFT ];			
    break;

  case 14:case 15:case 16:
    // slant left up
    pHitArea = m_HitArea[ LEFT_UP ];
    Areacount = m_HitAreaCount[ LEFT_UP ];			
    break;

  case 17:case 18:case 19:
    // up
    pHitArea = m_HitArea[ UP ];
    Areacount = m_HitAreaCount[ UP ];			
    break;

  default:
    // slant right up
    pHitArea = m_HitArea[ RIGHT_UP ];
    Areacount = m_HitAreaCount[ RIGHT_UP ];			
    break;
	
  }

  bool conflict = false;
  int includedCnt = 0;

  
  for(int i = 0; i < Areacount; i++){
   
    (pHitArea+i)->SetBasePos( (int)m_real_x, (int)m_real_y );
    int ret = (pHitArea+i)->Compare(Area);
    
    switch(ret){

    case AREA_INCLUDED:
      includedCnt++;
      break;

    case AREA_CONFLICT:
      conflict = true;
      break;

    case AREA_NO_CONFLICT:
      break;
    }

    if(conflict){
      break;
    }

  }

  if(conflict){

    // Miss !!
    return CROSS_NET_FISH;

  } else if(includedCnt == Areacount){

    // Catch Fish !!
    return WITHIN_NET_FISH;

  }

  return OUT_OF_NET_FISH;


  
}
