

import sk.uniba.fmph.pocprak.simplegraphics.GrGraphics;
/**
 * Trieda reprezentujuca stvouholnik vo vnutri ktoreho sa hybu castice a odrazaju od stien
 * Predpoklada sa, ze uzivatel zada suradnice vrcholov tak, aby bod (0,0) lezal
 * vnutri toho stvoruholnika. Tato podmienka sa nekontroluje
 */
public class biliard {
  public point A;
  public point B;
  public point C;
  public point D;

  public biliard(point A,point B,point C,point D){
    this.A=A;
    this.B=B;
    this.C=C;
    this.D=D;
  }

  /**
   * Vrati jednotlive hrany stvoruholnika ako usecky (segment). Cislovanie
   * hran je: 0-AB,1-BC,2-CD,3-DA
   */
  public segment seg(int i){
    switch(i){
      case 0: return new segment(A,B);
      case 1: return new segment(B,C);
      case 2: return new segment(C,D);
      case 3: return new segment(D,A);
    }
    return null; //toto nema nikdy nastat
  }

  /**
   * Vrati hit (teda cas a usecku) reprezentujucu udalost nasledujuceho narazu
   * castice p na stenu biliardu. Urobi to tak, ze vyskusa vsetky usecky (segmenty)
   * hranice biliardu, kedy do nich castica narazi a potom vyberie tu, do ktorej
   * narazi najskor
   */
  public hit nexthit(particle p){
    //vyhlada do ktoreho segmentu narazi najskor, teda v najmensom kladnom case
    //vsimnite si inicializaciu premennej nexthittime
    double nexthittime=Double.MAX_VALUE;
    segment hitsegment=null;
    int hitsegmentid =-1; //toto len aby to nebolo inicializovane na platne cislo segmentu
    for (int segmentid=0;segmentid<4;segmentid++){
      segment s= seg(segmentid);
      double hittime = hitTime(s,p);
      if (hittime >0 && hittime < nexthittime){
        nexthittime=hittime;
        hitsegment=s;
        hitsegmentid = segmentid;
      }
    }
    return new hit(nexthittime,hitsegment,hitsegmentid);
  }
  /**
   * Vrati cas, po ktorom castica narazi do priamky danej dvoma
   * bodmi. Vratena hodnota ma zapornu hodnotu ak nenarazi
   */
  public double hitTime(segment s, particle p){
    vector linedir = s.direction(); //jednotkovy vektor usecky s
    // body priamky su zadane symbolicky ako B1+u*linedir, kde u je parameter
    // draha castice ja zadana zymbolicy ako r+t*v, kde t je cas
    // priesecnik drahy a priamky sa riesi ako sustava rovnic o dvoch neznamych u,t
    // B1+u*linedir = r+t*v
    // t*v - u*linedir = B1-r
    // teraz tu formalnu rovnicu prepiseme do maticoveho tvaru
    double a11 = p.v.x;
    double a12 = p.v.y;
    double a21 = -linedir.x;
    double a22 = -linedir.y;
    double c1 = s.B1.x-p.r.x;
    double c2 = s.B1.y-p.r.y;

    //teraz klasicke riesenie rovnic o dvoch neznamych pomocou determinantov
    // vypocitame neznamu t teda dobu narazu
    double det = a11*a22-a12*a21;
    double det1 = c1*a22-c2*a21;

    if (det==0) return -1.; //toto zica sa pohybuje rovnobezne s priamkou, teda nenarazi
    return det1/det; // tento cas moze byt aj zaporny, co znamena, ze castica
                     // narazi v minulotsi, teda nenarazi
  }


  /**
  * Biliard sa vykresli na zobrazovacej ploche, ktora je dana
  * hodnotou GrGraphics g. Vyuziva sa tu balik
  * sk.uniba.fmph.pocprak.simplegraphics
  */
  public void draw(GrGraphics g){
    for (int i=0;i<4;i++){
      seg(i).draw(g);
    }
  }

}
