/*
* ball.h
* ball in Mondrian
* DIN Is Noise is released under GNU Public License 2.0
* DIN Is Noise is copyright (c) 2006-2024 Jagannathan Sampath
* For more information, please visit https://dinisnoise.org/
*/

#ifndef __ball__
#define __ball__

#include "trail.h"
#include "ball_ops.h"

struct rect;

struct ball { // a ball

	enum {NOTE = 0, NOISE};
	int trig_what; // trigger note or noise?
	static const char* trigstr [2];

  float x, y; // position

  // velocity - speed, vector, slope, slope inverse, is slope infinite?
	float V, vx, vy, vm, vm_1;
	int vm_inf; 

	int auto_rotate; // velocity vector auto rotating? 0 - no, 1 - anti-clockwise, -1 - clockwise
	float dtheta; // angle to rotate ball direction

  rect* R; // box in which it is bouncing
  int select; // selected?
  int frozen; // frozen?

	float pitch_mult; // to modulate pitch
	int mod; // 0 = no modulation, < 0 = modulate down, > 0 modulate up // for visual

	float vol_mult; // to scale triggered sound volume
	float attack_time; // time for note to rise to full volume
	float decay_time; // time for note to fall silent
	enum {SET_DECAY_TIME=1, SET_ATTACK_TIME, SET_VOL_MULT};

	// bouncer = bounces, wrecker = makes slits, healer = closes slits
	int type;
	static const char* types_str [4];
	enum {BOUNCER=0, WRECKER, HEALER, INVALID};  // ball types

	// to initialise new ball
	static float recent_attack_time; 
	static float recent_decay_time;
  static float recent_pitch_mult;

	int num_notes; // number of active notes triggered by this ball
	int del; // delete ball? when triggered sounds have decayed

	// operations
	turn op_turn; 
	speed op_speed; 
	teleport op_teleport; 
	Clone op_clone;
	Transform op_transform;

	void eval_ops ();

	// visual
	trail_t trail; // trail
	float r, g, b; // color

	// log
	static int ref; // to log if we deleted all balls on exit
  
	ball (int _type = BOUNCER);
	~ball () { --ref; }

	void init (int _type = BOUNCER);
  void set_velocity (float _x, float _y);
	void rotate_velocity (int dir);
	void calc_velocity_slope ();
  void update ();
	void set_type (int _type);
	void color_using_modulation ();
	void on_edge_hit (int e1, int e2, int cl, float& v, float xry, float yrx, float elb, float ewh, std::pair<float, float>& invl, int& eh);
  void print ();
	void clone_this (ball* C);

};
#endif
