/* Plik naglowkowy zawiera definicje typow i funkcje potrzebne do tworzenia i
*  obslugi elementu gry zwanego 'koralikami'.
*  Wyszukiwanie elementow ma zloznosc liniowa z powodu malej ilosci elementow.
*  Jesli zazyczysz sobie wiekszej ilosci to trzeba bedzie niestety zmienic algorytm.
*
*        autor: r.Q
*        licencja: GNU GPL
*
*/
#include <time.h>
#include <stdlib.h>
#include <windef.h>
#include "ustawieniaGry.h"

#ifndef _KORALIKI_H_
#define _KORALIKI_H_

typedef struct {                   //struktura opisuje pojedynczy koralik...
        POINT polozenie;           // ...polozenia jego srodka...
        bool fPoziomo;             // ...ustawienie koralika...
        bool fNawleczony;          // ...i czy gracz juz nawlokl koralik
        } KORALIK;
        
void UstawKoralik(KORALIK*, POINT*, bool, bool);
KORALIK* TworzKoraliki(ushort_t, ushort_t&, ushort_t&);
void RysujJedenKoralik(HDC&, KORALIK*);
void RysujKoraliki(HDC&, KORALIK*, ushort_t);
int ZnajdzKoralik(KORALIK*, POINT*, KIERUNEK);    // funkcja zwraca wartosc ujemna
                                                  // jesli nie odnajdzie koralik na podanej
                                                  // jako argument pozycji, lub wartosc bedaca
                                                  // indeksem elementu.
                                                  
void ZmienStan(KORALIK*);                         // funkcja zmienia stankoralika z nienawleczonego 
                                                  // na nawleczony

#ifndef _SETPOS_F_
#define _SETPOS_F_
POINT SetPos(int xMax, int yMax) {
         int xTmp, yTmp;
         POINT ptTemp;
         // ponizsze dzialanie sprawia, ze elementy znajduja sie w obrebie
         // widocznosci gracza
         xTmp = (rand() % (xMax - SREDNICA_KORALIKA)) + PROMIEN_KORALIKA;
         yTmp = (rand() % (yMax - SREDNICA_KORALIKA)) + PROMIEN_KORALIKA;
         // teraz trzeba nam skorygowac wyniki w taki sposob
         // aby mozliwe bylo przejscie igla przez srodek koralika
         xTmp -= (xTmp % WIELKOSC_KROKU);
         yTmp -= (yTmp % WIELKOSC_KROKU);
         ptTemp.x = xTmp;
         ptTemp.y = yTmp;
         return ptTemp;
}
#endif /* _SETPOS_F_ */

//////////////////////////////////Implementacja////////////////////////////////////////////////////
void UstawKoralik(KORALIK* pKoralik, POINT* ptPolozenie,
                  bool fPoziomo, bool fNawleczony) {
     pKoralik->polozenie = *ptPolozenie;
     pKoralik->fPoziomo = fPoziomo;
     pKoralik->fNawleczony = fNawleczony;
}
KORALIK* TworzKoraliki(ushort_t ile, ushort_t& xObszarGry, ushort_t& yObszarGry) {
    int i;
    KORALIK* pKoralik;
    POINT ptTemp;
    pKoralik = (KORALIK*)malloc((size_t)(ile * sizeof(KORALIK)));
    for(i = 0; i < ile; i++) {
          ptTemp = SetPos(xObszarGry, yObszarGry);
          UstawKoralik(&pKoralik[i], &ptTemp, rand() % 2, false);
    }
    return pKoralik;
}
void RysujJedenKoralik(HDC& hdc, KORALIK* pKoralik) {
     COLORREF clKoralik, clOdblask;
     HBRUSH hBrush;
     POINT ptTemp;
     clKoralik = (pKoralik->fNawleczony ? KOLOR_KORALIKA_NAWLECZONEGO : KOLOR_KORALIKA);
     clOdblask = (pKoralik->fNawleczony ? KOLOR_ODBLASKU_NAWLECZONEGO : KOLOR_ODBLASKU_KORALIKA);
     ptTemp = pKoralik->polozenie;

     hBrush = (HBRUSH)SelectObject(hdc, CreateSolidBrush(clKoralik));
     Ellipse(hdc, ptTemp.x - PROMIEN_KORALIKA,
             ptTemp.y - PROMIEN_KORALIKA,
             ptTemp.x + PROMIEN_KORALIKA,
             ptTemp.y + PROMIEN_KORALIKA);
     if(pKoralik->fPoziomo) {
          MoveToEx(hdc, ptTemp.x - PROMIEN_KORALIKA, ptTemp.y, NULL);
          LineTo(hdc, ptTemp.x + PROMIEN_KORALIKA, ptTemp.y);
     }
     else {
          MoveToEx(hdc, ptTemp.x, ptTemp.y - PROMIEN_KORALIKA, NULL);
          LineTo(hdc, ptTemp.x, ptTemp.y + PROMIEN_KORALIKA);
     }
     DeleteObject(SelectObject(hdc, hBrush));
     SelectObject(hdc, GetStockObject(NULL_PEN));
     hBrush = (HBRUSH)SelectObject(hdc, CreateSolidBrush(clOdblask));
     Ellipse(hdc, ptTemp.x - (4 * PROMIEN_KORALIKA / 5),
             ptTemp.y - (4 * PROMIEN_KORALIKA / 5),
             ptTemp.x - PROMIEN_KORALIKA / 5,
             ptTemp.y - PROMIEN_KORALIKA / 5);
     SelectObject(hdc, GetStockObject(BLACK_PEN));
     DeleteObject(SelectObject(hdc, hBrush));
}     
void RysujKoraliki(HDC& hdc, KORALIK* pKoraliki, ushort_t ile) {
     int i;
     for(i = 0; i < ile; i++)
           RysujJedenKoralik(hdc, &pKoraliki[i]);
}
int ZnajdzKoralik(KORALIK* pKoralik, POINT* ptPozycja, KIERUNEK kierunek, int ile) {
     int i;
     for(i = 0; i < ile; i++) {
        // jesli koralik nie jest nawleczony
        if(!pKoralik[i].fNawleczony) {
           // jesli zgadza sie polozenie i kierunek
           if((pKoralik[i].polozenie.x == ptPozycja->x) &&
              ((pKoralik[i].polozenie.y == ptPozycja->y) &&
               !(pKoralik[i].fPoziomo ^ (kierunek % 2 == 0)))) {
                return (i);
           }
        }
     }
     return (-1);
}
void ZmienStan(KORALIK* pKoralik) {
     pKoralik->fNawleczony = true;
}

#endif     // _KORALIKI_H_
