#include <iostream>
#include <string>
#include <cmath>
#include <ctime>
#include <cstdlib>
using namespace std;

//prototypes go here!


int getIntegerWithRange(string, int, int);
int getRandomInteger(int , int);

string menuPlayer(); //this fn made strictly for providing and reading in user option- has cout/cin
int playerAttack(string); //but most functions should be built without console out and console in
int dragonAttack(int, int , int); //but most functions should be built without cout/cin
void outputStatus(int, int); //this is a fn made strictly for cout
void outputDragonAttack(int);
int hpMod(string, int);

int main() {
  cout << "Welcome to Caitlin's Explicit Elicit Electric Ecstatic Enemies and Errors." << endl;
  srand(time(NULL)); rand();
  int maxHP = 30;
  int dragonMaxHP = 200;
  int playerHP = maxHP, dragonHP = dragonMaxHP;
  int numberOfHeals = 3;
  while (playerHP > 0 && dragonHP > 0) {
    string turnType = menuPlayer();
    dragonHP = dragonHP - playerAttack(turnType);
    playerHP = playerHP + hpMod(turnType,numberOfHeals);
    if (playerHP > maxHP) playerHP = maxHP;
    if (turnType == "heal") numberOfHeals--;
    int dav = getRandomInteger(1, 100);
    outputDragonAttack(dav);
    if (getRandomInteger(1, 100) > 10) {
      playerHP = playerHP - dragonAttack(dav, dragonHP, dragonMaxHP);
    }
    else {
      cout << "YOU DODGED - GREAT!" << endl;
    }
    outputStatus(playerHP, dragonHP);
  }
  //outputStatus(playerHP, dragonHP);  //doesn't use its return value because it is a void function
}

//it is customary to comment judiciously before each function
//describe inputs/outputs of the functions
//preconditions/postconditions of the variables
//and what the function is meant to do


//present a menu of options for the player
//return which option was selected
string menuPlayer() {
  string turn;
  while (turn != "light" && turn != "medium" &&
	 turn != "heavy" && turn != "heal") { 
    //&& turn != "dodge") {
    cout << "Please input your attack strength: " << endl;
    cout << "  light - a light attack " << endl;
    cout << "  medium - a medium attack " << endl;
    cout << "  heavy - a heavy attack " << endl;
    cout << "  heal - take a potion!" << endl;
    //cout << "  dodge - you try to dodge!" << endl;
    cin >> turn;
  }
  return turn;
}

//perform a specific attack from the player
//this attack is selected by the menuPlayer
//1 is a light attack with some heal, 2 is a medium attack with no heal, 3 is a heavy attack that also dmgs yourself
//uses randomness to determine amounts inside this function
int playerAttack(string attackType) {
  if (attackType == "light") {
    int n = getRandomInteger(1, 10);
    int sum = 0;
    for (int i = 0; i < n; i++) {
      sum = sum + getRandomInteger(1, 10);
    }
    return sum;
  }
  if (attackType == "medium") {
    int n = getRandomInteger(1, 5);
    int sum = 0;
    for (int i = 0; i < n; i++) {
      sum = sum + getRandomInteger(2, 20);
    }
    return sum;
  }
  if (attackType == "heavy") {
    return getRandomInteger(50, 95);
  }
  return 0;
}

//output some pretty expression for the user
//about what the dragon is doing to your 
//character. warning - expliit!
void outputDragonAttack(int num) {
  if (num <= 5) {
    cout << "The dragon is really smelly and it HURTS!" << endl;
  }
  else if (num <= 40) {
    cout << "The dragon uses dank memes!" << endl;
  }
  else {
    cout << "The dragon is too busy QQing to pay attention. Alt-F4 to reload this game." << endl;
  }
}

//perform a specific attack by the dragon
//randomness selects the specific attack
//1-5 means do a heavy dmg breathe fireball , 
//6-40 is a medium bite
//41-100 is a light claw
//uses randomness to determine amounts inside this function
int dragonAttack(int rnd, int curr, int max) {
  int multiplier = 1;
  if (curr < max / 2) { 
    multiplier = 2; 
  }
  if (rnd <= 5) {
    //heavy
    return multiplier*getRandomInteger(10, 20);
  }
  else if (rnd <= 40) {
    //medium
    return multiplier*getRandomInteger(5, 10);
  }
  else {
    //light
    return multiplier*getRandomInteger(1, 3);
  }
  return 0;
}

int hpMod(string turn, int numHeals) {
  if (turn == "heal") {
    if (numHeals > 0) {
      return getRandomInteger(10, 15);
    }
  }
  if (turn == "light") {
    return getRandomInteger(1, 2);
  }
  if (turn == "heavy") {
    return -getRandomInteger(1, 10);
  }
  return 0;
}


/* output the status of the players hp
   and the dragon's hps - including if
   either has died! */
void outputStatus(int php, int dhp) {
  if (php <= 0) {
    cout << "You have died! - Oh Noesz" << endl;
  }
  else if (php < 10) {
    cout << "You're almost dead Jim! " << endl;
  }
  else {
    cout << "You have " << php << " hps." << endl;
  }
  
  if (dhp <= 0) {
    cout << "You have slain the dragon! Yayz" << endl;
  }
  else {
    cout << "The dragon still has " << dhp << "hps." << endl;
  }
  //return; //you can have a return inside void functions
  //but it may not return a value
}



int getRandomInteger(int min, int max) {
  if (min > max) { int t = min; min = max; max = t; }
  return rand() % (max - min + 1) + min;
}
