import com.swath.*;
import com.swath.cmd.*;

import java.io.*;
import java.util.*;

/**
 * Smart Explore
 *
 * Synopsis: Performs Holo and/or Density scans while Exploring.
 *
 * Description:
 *  This script takes a starting destination sector as a parameter.  The script will automatically
 *  move you to the destination, while optionally holo/density scanning. if you
 *  come across a port that is compatable with your supplies onboard it will trade
 *  at it.
 *  If you select density scan only, then the script will halt when it encounters an
 *  anomaly(option) or a density which is not either 100 or 0.
 *  This means that if you select 1 figter in the fighter area and are density and holoscanning
 *  that it will not enter any sector with enemy figts in them. rendering you
 *  invisible to other players..
 *  If you select density and holo, then the script will perform a holo scan when the
 *  density is not either 100 or 0, and will halt if there are figs (option), traders(not yet available),
 *  planets(not yet available), or anomalies(option).
 *  The 'Holo Trigger' parameter tells the script how many warps there have to be to
 *  force a holo scan.  For example, it may be desired to always perform a holo scan when
 *  you are in a sector with >=4 unexplored warps.  Set to 0 to never trigger, and set
 *  to 1 to always trigger.
 *
 * @Special thanks RatBastard for Concept work
 *
 * @Author CSG
 * jmelsone@insight.rr.com
 * @version 0.1.5 12/21/01
 *   -Added Loop to continuously run from start sector to next sequential sector.
 *   -Fixed 7000 sector limitation script will now use sectors in game info.
 *   -Prevent your own mines/whatever from halting script
 *   -Don't halt script when mines belong to you or your corp.
 *   -Don't halt script when figs belong to your corp.
 *   -Allow for port trading during move
 *   -Compartmentalized movement
 * @version 0.2.1 12/23/01
 *   -Removed Tokenizeer in attempt to stop crashes replaced with PlotCourse()
 *   -SmartFlee to fed on find something bad..
 */
public class SmartExplore extends UserDefinedScript {

        /*****************HELPFUL USER DEFAULTS*******************/
        protected static final int DEFAULT_HOLO_TRIG = 1;
        protected static final boolean DEFAULT_DENSITY_SCAN = true;
        protected static final boolean DEFAULT_HOLO_SCAN = true;
        protected static final boolean DEFAULT_ANOM_HALT = false;
        protected static final int DEFAULT_FIG_HALT = 10000;
        /*********************************************************/

        /* Other class variables */
        protected static final int MAX_SCAN = 6;
        protected static final String TITLE = "SmartExplore";
        protected boolean bHaveHScanner = false;
        protected boolean bHaveDScanner = false;
        /* Class Parameters */
        protected Parameter parDScanner;
        protected Parameter parHScanner;
        protected Parameter parDest;
        protected Parameter parHoloTrig;
        protected Parameter parAnomHalt;
        protected Parameter parFigHalt;



public String getName()
{
        return TITLE;
} /* getName() */

public boolean initScript() throws Exception
{
        /* check prompt */
        if(!atPrompt(Swath.COMMAND_PROMPT)) {
                MessageBox.exec("Must be at command prompt.",
                                "Error",
                                MessageBox.ICON_ERROR,
                                MessageBox.TYPE_OK);
                return false;
        }

        /* Add Destination Sector Parameter */
        parDest = new Parameter("Start with Sector?");
        parDest.setType(Parameter.INTEGER);
        parDest.setIntegerRange(1,20000);
        parDest.setInteger(Swath.main.currSector());
        registerParam(parDest);


        if (Swath.ship.hasDensityScanner()) {
                /* Add Density Scanner Sector Parameter */
                parDScanner = new Parameter("Use Density Scanner?");
                parDScanner.setType(Parameter.BOOLEAN);
                parDScanner.setBoolean(DEFAULT_DENSITY_SCAN);
                registerParam(parDScanner);
                bHaveDScanner = true;

                /* Add Halt on Anomaly option */
                parAnomHalt = new Parameter("Halt on Anomalies?");
                parAnomHalt.setType(Parameter.BOOLEAN);
                parAnomHalt.setBoolean(DEFAULT_ANOM_HALT);
                registerParam(parAnomHalt);
        }


        if (Swath.ship.hasHoloScanner()) {
                /* Add Holo Scanner Sector Parameter */
                parHScanner = new Parameter("Use Holo Scanner?");
                parHScanner.setType(Parameter.BOOLEAN);
                parHScanner.setBoolean(DEFAULT_HOLO_SCAN);
                registerParam(parHScanner);
                bHaveHScanner = true;

                /* Add Holo Trigger Parameter */
                parHoloTrig = new Parameter("Holo Scan Trigger:");
                parHoloTrig.setType(Parameter.INTEGER);
                parHoloTrig.setIntegerRange(0,10);
                parHoloTrig.setInteger(DEFAULT_HOLO_TRIG);
                registerParam(parHoloTrig);

                /* Add Fighter halt parameter */
                parFigHalt = new Parameter("How many fighters before halting?");
                parFigHalt.setType(Parameter.INTEGER);
                parFigHalt.setInteger(DEFAULT_FIG_HALT);
                parFigHalt.setIntegerRange(1,100000);
                registerParam(parFigHalt);
        }

return true;
} /* initScript() */


public boolean runScript() throws Exception
{
int iDest;                      // Destination sector
int iCurDest, iDensity;
String strPlot;
Sector secCurDest;
        /* How many sectors in this game */
        int Gsectors = Swath.main.sectors();
        iDest = parDest.getInteger();   /* Get destination sector */
        /* start with dest sector and increment dest sector sequentially */
        for (iDest = iDest; iDest < Gsectors; iDest++)
        {
         Sector dest = Swath.getSector(iDest);

             /* Only set a destination sector that is unexplored */
             if (dest.isUnexplored())
                {
                MoveToSector(iDest);
                }
          }
return true;
} /* runScript() */

public boolean MoveToSector(int Location) throws Exception
{
        boolean bHScan = false;         // Do we want to holo scan?
        boolean bDScan = false;         // Do we want to density scan?
        boolean bAnomFound = false;     // Anomaly found in path
        boolean bUnknownDen = false;    // Unknown density in path
        boolean bSomethingBad = false;  // Encountered a reason to stop (fig, trader, planet)
        int iDest;                      // Destination sector
        int iCurDest, iDensity;
        int iFromLoc;
        int iCurLoc;


        String Message;
        Sector secCurDest;



        /* Check to see if we have scanners, and if so, do we want to use them? */
        if (bHaveHScanner)
           {
           bHScan = parHScanner.getBoolean();
           }
        if (bHaveDScanner)
           {
           bDScan = parDScanner.getBoolean();
           }

       /* Keep plotting course, and moving, until we've reached our destination */

        EnterComputer.exec();
        iFromLoc = Swath.sector.sector();
        int [] iCurCourse = PlotCourse.exec(iFromLoc,Location);
        LeaveComputer.exec();

        int seccount = 1;
        while (Swath.sector.sector() != Location)
              {
              Message = String.valueOf(iCurCourse[seccount]);

              // do we have density scan checked
              if (bDScan)
                {

                  ScanSector.exec(ScanSector.DENSITY_SCAN);
                  secCurDest = Swath.getSector(iCurCourse[seccount]);
                  iDensity = secCurDest.density();
                  bAnomFound = secCurDest.anomality();
               // Analyze the scan
                  if ( (iDensity != 0) && (iDensity !=100) )
                     {
                     bUnknownDen = true;
                     }
                  } // end density scan
                 // Is holo scanning option turned on?
              if (bHScan)
                 {

                 // Get number of unexplored sectors
                 int iUnExplored = 0;
                 int iWarps[] = Swath.sector.warpSectors();
                 for (int i=0; i < Swath.sector.warps(); i++)
                     {
                     Sector sec = Swath.getSector(iWarps[i]);
                     if (sec.isUnexplored())
                        {
                        iUnExplored++;
                        }
                     }
                  // Do we perfrom holo scan?
                  if ((iUnExplored >= parHoloTrig.getInteger()) || (bUnknownDen))
                     {
                     // Start the scan

                     ScanSector.exec(ScanSector.HOLO_SCAN);
                     secCurDest = Swath.getSector(iCurCourse[seccount]);


                       if (((secCurDest.fighters() >= parFigHalt.getInteger()) &&
                          (!secCurDest.ftrOwner().isYou())) ||
                          ((secCurDest.armidMines() > 0) &&
                          (!secCurDest.armidOwner().isYou())))
                          {
                           bSomethingBad = true;
                          } // end something bad}
                          else
                              {
                               bSomethingBad = false;
                               } // end nothing bad
                        } // end check unexplored
                   } // end do we have a holoscan
               // Should we abort the move? //
               if (((bAnomFound) && (parAnomHalt.getBoolean())) ||
                  (bSomethingBad))
                  {

                   Move.exec(Swath.main.stardock());
                   EnterComputer.exec();
                   SetAvoidedSectors.exec(iCurCourse[seccount]);
                   LeaveComputer.exec();
                   bSomethingBad = false;

                   return false;
                   } // end abort move

               Move.exec(iCurCourse[seccount]);
               seccount = seccount + 1;
              } //end while

              DropTakeFighters.exec(1, Swath.CORPORATE, Swath.TOLL_FTRS);

  return true;

 } // End MoveToSector
} /* class SmartExplore */
