#include <iostream>
#include <cmath>
#include <climits>
using namespace std;

void menu(void);

const char version[] = "1.5.3.4", prompt[] = "Enter a number (0 = back to Menu): ";

void prime_calc(int t)
{
  unsigned int i = 1,n = 0,pn;
  bool isprime;
  givet2num:
  if (t == 2) {
    cout << prompt;
    cin >> pn;
    if (pn == 0) {
      menu();
      return;
    } else if (pn >= INT_MAX) {
      cout << "Value too high! ";
      goto givet2num;
    }
    i = 1;
    n = 0;
  }
  while (true) {
    if (t == 1) {
      givet1num:
      cout << prompt;
      cin >> i;
      if (i == 0) {
        menu();
        return;
      } else if (i >= INT_MAX) {
        cout << "Value too high! ";
        goto givet1num;
      }
    }
    if (i == 2) {
      isprime = true;
    } else if ((i <= 1) || (i%2 == 0)) {
      isprime = false;
    } else {
      isprime = true;
      for (int j = i / 2 + 1;j >= 2 && isprime;j--) {
        int r = i%j;
        if (r == 0) {
          isprime = false;
        } else {
          isprime = true;
        }
      }
    }
    if (t == 1) {
      cout << i << " ";
      if (isprime) {
        cout << "IS";
      } else {
        cout << "is NOT";
      }
      cout << " a prime number." << endl;
    } else {
      if (isprime) {
        n++;
        if (t == 2) {
           if ((isprime) && (n == pn)) {
             cout << "Prime number #" << n << " is: " << i << endl;
             goto givet2num;
           }
        } else {
          cout << n << ". " << i << endl;
        }
      }
      if (i >= INT_MAX) {
        cout << "Maximum value reached. ";
        system("PAUSE");
        menu();
        return;
      }
      i++;
    }
  }
}

void eras_sall(void)
{
  while (true) {
    unsigned int s,i,r,n,o,m;
    double t1,t2;
    givenum:
    cout << prompt;
    cin >> n;
    if (n == 0) {
      menu();
      return;
    } else if (n >= 360000000) {
      cout << "Value too high! ";
      goto givenum;
    }
    bool* tal = new bool[n + 1];
    for (i = 0; i <= n; i++) {
      tal[i] = true;
    }
    i = 2;
    t1 = (double)n;
    t2 = sqrt(t1);
    r = (int)t2;
    while (i <= r) {
      for(m = 2*i;m <= n;m += i) {
        tal[m] = false;
      }
      do {
        i++;
      } while (tal[i] == false);
    }
    o = 1;
    for (s = 2;s <= n;s++) {
      if (tal[s] == true) {
        cout << o++ << ". " << s << endl;
      }
    }
  }
}

void help(int mode = 0)
{
  int type = 0;
  switch (mode) {
    case 0:
      system("CLS");
      cout << "PrimeSuite - Help" << endl << "=================" << endl;
      cout << "1. Manual mode" << endl;
      cout << "2. Inverted mode" << endl;
      cout << "3. Erastoteles mode" << endl;
      cout << "4. Loop mode" << endl;
      cout << "------------------------------" << endl;
      cout << "0. Back to Menu" << endl << endl;
      choice:
      cout << "Choose a number: ";
      cin >> type;
      switch(type) {
        case 1: help(1); break;
        case 2: help(2); break;
        case 3: help(3); break;
        case 4: help(4); break;
        case 0: menu(); return;
        default: cout << endl << "Invalid choice! "; goto choice;
      }
      break;
    case 1:
      system("CLS");
      cout << "PrimeSuite - Help - Manual mode" << endl << "===============================" << endl;
      cout << "In manual mode, you will be asked to enter a value. The program will then check" << endl;
      cout << "if the given value is a prime number." << endl;
      cout << "(E.G. You enter 3, the program will return that 3 is a prime number.)" << endl << endl;
      system("PAUSE");
      help();
      break;
    case 2:
      system("CLS");
      cout << "PrimeSuite - Help - Inverted mode" << endl << "=================================" << endl;
      cout << "In inverted mode, you will be asked to enter a value. The program will then" << endl;
      cout << "look up the prime number with that number." << endl;
      cout << "(E.G. You enter 18, the program will return prime number #18.)" << endl << endl;
      system("PAUSE");
      help();
      break;
    case 3:
      system("CLS");
      cout << "PrimeSuite - Help - Erastoteles mode" << endl << "====================================" << endl;
      cout << "In Erastoteles mode, you will be asked to enter a value. The program will then" << endl;
      cout << "check all numbers from 1 up to the value (including it) if they are prime" << endl;
      cout << "numbers, using the \"Sieve of Erastoteles\"-method. The maximal value you can" << endl;
      cout << "enter is 359999999, because of system limitations." << endl;
      cout << "(E.G. You enter 1000, the program will return all prime numbers from 1 up to" << endl;
      cout << "1000 (including 1000).)" << endl << endl;
      system("PAUSE");
      help();
      break;
    case 4:
      system("CLS");
      cout << "PrimeSuite - Help - Infinite mode" << endl << "=================================" << endl;
      cout << "In loop mode, the program will check all numbers from 1 and up, until the value" << endl;
      cout << "reaches " << INT_MAX << " or you press Ctrl+C (will exit the program)." << endl << endl;
      system("PAUSE");
      help();
      break;
  }
}

void about(bool gotomenu = true)
{
  system("CLS");
  cout << "PrimeSuite - About" << endl;
  cout << "==================" << endl << endl;
  cout << "Powered by Crime " << version << endl << endl;
  cout << "\t\t(c) 2004 Jocke \"Firetech\" Andersson" << endl << endl;
  cout << "------------------" << endl;
  system("PAUSE");
  if (gotomenu)
  {
    menu();
    return;
  }
}


void menu(void)
{
  int type = 0;
  system("CLS");
  cout << "PrimeSuite - Menu" << endl << "=================" << endl;
  cout << "1. Manual mode" << endl;
  cout << "2. Inverted mode" << endl;
  cout << "3. Erastoteles mode" << endl;
  cout << "4. Loop mode" << endl;
  cout << "------------------------------" << endl;
  cout << "5. Help" << endl;
  cout << "6. About" << endl;
  cout << "------------------------------" << endl;
  cout << "0. Exit" << endl << endl;
  choice:
  cout << "Choose a number: ";
  cin >> type;
  switch(type) {
    case 1: prime_calc(1); break;
    case 2: prime_calc(2); break;
    case 3: eras_sall(); break;
    case 4: prime_calc(3); break;
    case 5: help(); break;
    case 6: about();
    case 0: return;
    default: cout << endl << "Invalid choice! "; goto choice;
  }
}

void main(void)
{
  menu();
  about(false);
}

