//http://user.it.uu.se/~jesperw/se/qna/frekvenser.shtml
#include <iostream>
#include <conio.h>
#include <cstdlib>
#include <ctime>
#include <windows.h>
using namespace std;

void getpos( int & x, int & y );
void gotopos( int x, int y );

int main( void )
{
  srand( time( 0 ) );

  int rFreq, gFreq, temp, xpos, ypos, fStep = 10;
  bool quit = false, game;

  while ( !quit )
  {
    system( "cls" );
    cout << "beepGuess\n=========\n\n";
    cout << " N \tNy ton\n";
    cout << " S \t\x8Endra sv\x86righetsgrad\n";
    cout << " L \tLyssna p\x86 tonen\n";
    cout << " G \tLyssna p\x86 din gissning\n";
    cout << " I \tSkriv in gissning\n";
    cout << "\x19,\x18\tGrovjustera gissning\n";
    cout << "\x1B,\x1A\tFinjustera gissning\n";
    cout << " T \tTesta gissning\n";
    cout << " A \tAvsluta\n";
    cout << "\n------- ------ ----- ---- --- -- -\n\n";
    cout << "Sv\x86righetsgrad: " << 6 - ( fStep / 2 ) << "\n";

    rFreq = int( double( 128 + rand() % 960 ) / fStep ) * fStep; //slumpa fram ton (128-1088 Hz, med steglängd fStep).
    Beep( rFreq, 100 );

    gFreq = int( double( 608 ) / fStep ) * fStep; //fixa rätt steglängd. utgå från mitten av intervallet.

    getpos( xpos, ypos );
    cout << "Gissad frekvens: " << gFreq << " Hz  ";

    game = true;
    while ( game )
    {
      switch ( tolower( getch() ) )
      {
        case 0: //Borland-style (BCC)
        case 224: //MinGW-style
          temp = gFreq;
          switch ( getch() )
          {
            case 77:
              gFreq += fStep;
            break;
            case 75:
              gFreq -= fStep;
            break;
            case 72:
              gFreq += ( fStep * 10 );
            break;
            case 80:
              gFreq -= ( fStep * 10 );
            break;
          }
          if ( ( gFreq < 128 ) || ( gFreq > 1088 ) )
          {
            gFreq = temp;
          }
          else if ( temp != gFreq )
          {
            gotopos( xpos, ypos );
            cout << "Gissad frekvens: " << gFreq << " Hz  ";
            Beep( gFreq, 25 );
          }
        break;
        case 's':
          fStep -= 2;
          if ( fStep == 0 )
          {
            fStep = 10;
          } //ingen break här för att vi ändå ska köra nytt spel.
        case 'n':
          game = false;
        break;
        case 'l':
          Beep( rFreq, 100 );
        break;
        case 'g':
          Beep( gFreq, 100 );
        break;
        case 'i':
          do
          {
            gotopos( xpos, ypos );
            cout << "Gissad frekvens:          ";
            gotopos( xpos + 17, ypos );
            cin >> gFreq;
            gFreq = int( double( gFreq ) / fStep ) * fStep; //fixa rätt steglängd.
          }
          while ( ( gFreq < 128 ) || ( gFreq > 1088 ) );
          gotopos( xpos, ypos );
          cout << "Gissad frekvens: " << gFreq << " Hz  "; //max 34 tecken
          Beep( gFreq, 100 );
        break;
        case 't':
          gotopos( xpos, ypos );
          if ( gFreq == rFreq )
          {
            cout << "R\x84tt svar! (" << rFreq << " Hz)              \n";
            if ( fStep > 2 )
            {
              cout << "\x99kar sv\x86righetgraden med ett steg.\n";
              fStep -= 2;
            }
          }
          else
          {
            cout << "Fel svar!                         \n\n";
            cout << "R\x84tt svar: " << rFreq << " Hz\n";
            cout << "Din gissning: " << gFreq << " Hz\n";
            cout << "Skillnad: " << ( ( rFreq - gFreq ) < 0 ? gFreq - rFreq : rFreq - gFreq ) << " Hz\n";
          }
          cout << '\n';
          system( "pause" );
          game = false;
        break;
        case 'a':
          game = false;
          quit = true;
        break;
      }
    }
  }
  cout << endl;
  return 0;
}

void getpos( int & x, int & y )
{
  HANDLE hConsole = GetStdHandle( STD_OUTPUT_HANDLE );
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  GetConsoleScreenBufferInfo( hConsole, & csbi );
  x = csbi.dwCursorPosition.X + 1;
  y = csbi.dwCursorPosition.Y + 1;
}

void gotopos( int x, int y )
{
  COORD scrn;
  HANDLE hOuput = GetStdHandle( STD_OUTPUT_HANDLE );
  scrn.X = x - 1;
  scrn.Y = y - 1;
  SetConsoleCursorPosition( hOuput, scrn );
}

