/*
Copyright (C) by Dmitry E. Oboukhov 2006, 2007

  This package is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
  
  This package is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this package; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
*/
#include <stdio.h>

#include "report.h"

#ifdef __WIN32__
#define LPF     "%I64d"
#else
#define LPF     "%lld"
#endif

//===================================================================
// печатает флоты атакующего и защитника
//===================================================================
static void print_fleets(const int *attacker, const int *defender)
{
  int i;
  printf("\tAttacker\n");
  for (i=0; i<UNITS_COUNT; i++)
  {
    if (attacker[i])
      printf("\t\t%20s: %d\n", units[i].name, attacker[i]);
  }
  printf("\tDefender\n");
  for (i=0; i<UNITS_COUNT; i++)
  {
    if (defender[i])
      printf("\t\t%20s: %d\n", units[i].name, defender[i]);
  }
}

//===================================================================
// печатает флоты атакующего и защитника (по результатам симуляции)
//===================================================================
static void print_fleets_result(const sim_result * sr)
{
  print_fleets(sr->attacker.unit, sr->defender.unit);
}
//===================================================================
// Печатает результаты симуляции (задание)
//===================================================================
static void print_simulate_task(const sim_info * sim, 
  const char *title, int print_resources)
{
  int i;
  
  printf("\n[%s]\n", title);
  print_fleets(sim->attacker.unit, sim->defender.unit);

  if (print_resources)
  {
    printf("\n\t\t%20s: %d\n", "Defender metal", 
        sim->defender_resource.metal);
    printf("\t\t%20s: %d\n", "Defender crystal", 
        sim->defender_resource.crystal);
    printf("\t\t%20s: %d\n", "Defender deut", 
        sim->defender_resource.deut);
  }
}
//===================================================================
// печатает средний результат
//===================================================================
static void print_average(const sims_result * sr)
{
  int i;
  printf("\n[Average simulation]\n\tAttacker\n");

  for (i=0; i<UNITS_COUNT; i++)
  {
    if (sr->task.attacker.unit[i])
    {
      printf("\t\t%20s: %-8.2lf\n", 
          units[i].name, sr->attacker.unit[i]);
    }
  }
  
  printf("\tDefender\n");

  for (i=0; i<UNITS_COUNT; i++)
  {
    if (sr->task.defender.unit[i])
    {
      printf("\t\t%20s: %-8.2lf\n", 
          units[i].name, sr->defender.unit[i]);
    }
  }
  
  printf("\n[Average capacity after combat]\n");
  printf("Attacker: " LPF "\nDefender: " LPF "\n", 
      sr->attacker.capacity, sr->defender.capacity);

  resource max_res=sr->task.defender_resource;
  max_res.metal>>=1; max_res.crystal>>=1; max_res.deut>>=1;
  int max_total=max_res.metal+max_res.crystal+max_res.deut;
  int total=sr->attacker_plunder.metal+
    sr->attacker_plunder.crystal+sr->attacker_plunder.deut;
  
  printf("\n[Attacker plunder]\n");
  printf(
      "  Metal: %10d (%3d%%)\n"
      "Crystal: %10d (%3d%%)\n"
      "   Deut: %10d (%3d%%)\n"
      "  Total: %10d (%3d%%)\n"
      "Needed Small chargo: %d\n"
      "Needed Large chargo: %d\n",
        sr->attacker_plunder.metal,
        max_res.metal?sr->attacker_plunder.metal*100/max_res.metal:100,
        sr->attacker_plunder.crystal,
        max_res.crystal?sr->attacker_plunder.crystal*100/max_res.crystal:100,
        sr->attacker_plunder.deut,
        max_res.deut?sr->attacker_plunder.deut*100/max_res.deut:100,
        total, max_total?total*100/max_total:100,
        sr->chargo.small, sr->chargo.large);
}

//===================================================================
// печатает инфу о потерях
//===================================================================
static void print_debris(const debris *dbr,
    const char *title)
{
  printf("\n[%s]\n", title);

  printf(
    "Attacker loss: metal=" LPF " crystal=" LPF " deuterium=" LPF "\n"
    "Defender loss: metal=" LPF " crystal=" LPF " deuterium=" LPF "\n"
    "Common loss: metal=" LPF " crystal=" LPF " deuterium=" LPF "\n\n"

    "Debris with ground: metal=" LPF " crystal=" LPF "\n"
    "Debris without ground: metal=" LPF " crystal=" LPF "\n",

    dbr->attacker.all.metal, dbr->attacker.all.crystal, dbr->attacker.all.deut,
    dbr->defender.all.metal, dbr->defender.all.crystal, dbr->defender.all.deut,
    dbr->both.all.metal, dbr->both.all.crystal, dbr->both.all.deut,
    NORMALIZE_DEBRIS(dbr->both.all.metal*30/100), 
    NORMALIZE_DEBRIS(dbr->both.all.crystal*30/100),
    NORMALIZE_DEBRIS(dbr->both.fleet.metal*30/100), 
    NORMALIZE_DEBRIS(dbr->both.fleet.crystal*30/100)
  );

  printf(
      "Recyclers with ground: " LPF 
      "\nRecyclers without ground: " LPF "\n",
      dbr->recyclers.all, dbr->recyclers.fleet);

  printf(
    "Chance moon with ground: %d%%\n"
    "Chance moon without ground: %d%%\n",
    dbr->moon.all, dbr->moon.fleet);
}

//===================================================================
// печатает результаты симуляции
//===================================================================
void print_report(const sims_result *sr)
{
  print_simulate_task(&sr->task, "Simulate task", 1);
  printf("\n[Simulate info]\n");
  printf("Rounds: %1.2lf (%d, %d)\n", 
      sr->rounds.average, sr->rounds.min, sr->rounds.max);
  printf("Simulations: %d\n", sr->sim_count);
  
  printf("Attacker win: %d/%d (%d%%)\n", 
      sr->wins.attacker, 
      sr->sim_count, 
      100*sr->wins.attacker/sr->sim_count);
  printf("Defender win: %d/%d (%d%%)\n", 
      sr->wins.defender, 
      sr->sim_count, 
      100*sr->wins.defender/sr->sim_count);

  printf("\n[Best attacker]\n");
  print_fleets_result(&sr->best_attacker);
  printf("\n[Worst attacker]\n");
  print_fleets_result(&sr->worst_attacker);
  printf("\n[Best defender]\n");
  print_fleets_result(&sr->best_defender);
  printf("\n[Worst defender]\n");
  print_fleets_result(&sr->worst_defender);

  print_debris(&sr->debris, "Average debris");
  print_debris(&sr->min_debris.debris, "Minimum debris");
  print_debris(&sr->max_debris.debris, "Maximum debris");

  print_average(sr);
}
//===================================================================
