package player.tasks;

import logging.Logger;
import scg.Util;
import scg.gen.ChallengeKind;
import scg.gen.OfferTrans;
import scg.gen.OfferedChallenge;
import scg.gen.PlayerContext;
import scg.gen.ProblemType;
import scg.gen.Config;
import edu.neu.ccs.demeterf.lib.List;
import player.PlayerFactory;

/** Offer new Challenges, at good prices, that are not currently offered. */
public class OfferTask {
    /** Offer Secret challenges?? */
    protected boolean noSecrets = PlayerFactory.globalOptionSet(PlayerFactory.NOSECRETS);
    protected boolean allSecrets = PlayerFactory.globalOptionSet(PlayerFactory.ALLSECRETS);
    protected boolean fastPitch = PlayerFactory.globalOptionSet(PlayerFactory.FASTPITCH);
    protected int offerAmt;
    
    protected final Logger log;
    protected final Config config;

    
    /** Create a OfferTask with the given Logger */
    public OfferTask(Logger l, Config cfg){
        log = l;
        config = cfg;
        String arg = PlayerFactory.opitonArgument(PlayerFactory.OFFER);
        offerAmt = 0;
        if(arg.length() > 0)
            offerAmt = Integer.parseInt(arg); 
    }

    /** Do the actual creation/offering of new Challenges */
    public List<OfferTrans> offer(PlayerContext context){
        // Leave space for a single reoffer...
        final int MAX_OFFERS = offerAmt > 0 ? offerAmt : (context.getConfig().getMaxProposals()-1);
        log.notify("Offering "+MAX_OFFERS+" challenges...");
        return create(MAX_OFFERS, context.getAllOffered().map(new List.Map<OfferedChallenge, ProblemType>() {
            public ProblemType map(OfferedChallenge off){
                return off.getPred();
            }
        }));
    }

    public List<OfferTrans> create(int many, List<ProblemType> ts){
        if (many == 0)return List.create();
        OfferTrans ot = freshTrans(ts);
        log.notify("Offering a *"+(ot.getKind().isSecret()?"Secret":"Classic")+"* Challenge : "+ot.getPred());
        return create(many - 1, ts.push(ot.getPred())).push(ot);
    }

    public OfferTrans freshTrans(List<ProblemType> ts){
        return freshTrans(ts, 0.5 + Util.random() * 0.5);
    }
    public ChallengeKind getKind(){
        ChallengeKind kind = (!config.getHasSecrets() ||
                (!allSecrets && (noSecrets || Util.coinFlip())))
                ? ChallengeKind.ALL : ChallengeKind.SECRET;
        return kind;
    }
    public OfferTrans freshTrans(List<ProblemType> ts, double price){
        ProblemType pt;
        do {
            pt = ProblemType.random();
        } while (ts.contains(pt));
        return new OfferTrans(getKind(), pt, price);
    }
}

