/**
* Copyright (c) 2005-2017, KoLmafia development team
* http://kolmafia.sourceforge.net/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* [1] Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* [2] Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* [3] Neither the name "KoLmafia" nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package net.sourceforge.kolmafia.swingui.panel;
import java.awt.BorderLayout;
import java.util.Hashtable;
import javax.swing.Box;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.java.dev.spellcast.utilities.JComponentUtilities;
import net.java.dev.spellcast.utilities.LockableListModel;
import net.sourceforge.kolmafia.AdventureResult;
import net.sourceforge.kolmafia.KoLmafia;
import net.sourceforge.kolmafia.RequestThread;
import net.sourceforge.kolmafia.SpecialOutfit;
import net.sourceforge.kolmafia.listener.Listener;
import net.sourceforge.kolmafia.listener.PreferenceListenerRegistry;
import net.sourceforge.kolmafia.objectpool.IntegerPool;
import net.sourceforge.kolmafia.objectpool.ItemPool;
import net.sourceforge.kolmafia.persistence.ConcoctionDatabase;
import net.sourceforge.kolmafia.persistence.ItemDatabase;
import net.sourceforge.kolmafia.preferences.Preferences;
import net.sourceforge.kolmafia.request.CreateItemRequest;
import net.sourceforge.kolmafia.request.StorageRequest;
import net.sourceforge.kolmafia.request.UseItemRequest;
import net.sourceforge.kolmafia.swingui.widget.AutoHighlightSpinner;
import net.sourceforge.kolmafia.swingui.widget.CreationSettingCheckBox;
import net.sourceforge.kolmafia.utilities.InputFieldUtilities;
public class CreateSpecialPanel
extends InventoryPanel
{
private static LockableListModel temp;
static {
temp = new LockableListModel();
temp.add( "(reserved for list of manual recipes)");
}
public CreateSpecialPanel()
{
super( "create item", "create & use", temp, false );
JPanel filterPanel = new JPanel();
filterPanel.add( new CreationSettingCheckBox(
"require in-a-boxes", "requireBoxServants", "Do not cook/mix without -in-the-box" ) );
filterPanel.add( new CreationSettingCheckBox(
"repair on explosion", "autoRepairBoxServants",
"Automatically repair -in-the-box on explosion" ) );
filterPanel.add( new CreationSettingCheckBox(
"use closet", "autoSatisfyWithCloset", "Look in closet for ingredients" ) );
this.northPanel.add( filterPanel, BorderLayout.NORTH );
this.northPanel.add( new InvSlider(), BorderLayout.EAST );
Box box = Box.createVerticalBox();
Box subbox = Box.createHorizontalBox();
subbox.setAlignmentX( 0.0f );
subbox.add( Box.createGlue() );
subbox.add( new JLabel( "Value of ingredients already in inventory:", JLabel.RIGHT ) );
box.add( subbox );
box.add( Box.createGlue() );
box.add( new JLabel( "Value of a turn spent crafting:" ) );
box.add( new PrefSpinner( "valueOfAdventure" ) );
box.add( Box.createGlue() );
box.add( new JLabel( "Value of a Nash Crosby's Still use:" ) );
box.add( new PrefSpinner( "valueOfStill" ) );
box.add( Box.createGlue() );
box.add( new JLabel( "Value of a Tome summon:" ) );
box.add( new PrefSpinner( "valueOfTome" ) );
box.add( Box.createGlue() );
box.add( new JLabel( "List below is not implemented yet:" ) );
this.northPanel.add( box, BorderLayout.CENTER );
//this.setFixedFilter( food, booze, equip, other, true );
//ConcoctionDatabase.getCreatables().updateFilter( false );
}
@Override
public void addFilters()
{
}
@Override
public void actionConfirmed()
{
Object[] items = this.getSelectedValues();
// Disabled for now
for ( int i = 0; i < 0*items.length; ++i )
{
CreateItemRequest selection = (CreateItemRequest) items[ i ];
Integer value =
InputFieldUtilities.getQuantity(
"Creating multiple " + selection.getName() + ", " + (selection.getQuantityPossible() + selection.getQuantityPullable())
+ " possible", selection.getQuantityPossible() + selection.getQuantityPullable(), 1 );
int quantityDesired = ( value == null ) ? 0 : value.intValue();
if ( quantityDesired < 1 )
{
continue;
}
KoLmafia.updateDisplay( "Verifying ingredients..." );
int pulled = Math.max( 0, quantityDesired - selection.getQuantityPossible() );
selection.setQuantityNeeded( quantityDesired - pulled );
SpecialOutfit.createImplicitCheckpoint();
RequestThread.postRequest( selection );
SpecialOutfit.restoreImplicitCheckpoint();
if ( pulled > 0 && KoLmafia.permitsContinue() )
{
int newbudget = ConcoctionDatabase.getPullsBudgeted() - pulled;
RequestThread.postRequest( new StorageRequest(
StorageRequest.STORAGE_TO_INVENTORY,
new AdventureResult[] { ItemPool.get( selection.getItemId(), pulled ) } ) );
ConcoctionDatabase.setPullsBudgeted( newbudget );
}
}
}
@Override
public void actionCancelled()
{
Object[] items = this.getSelectedValues();
// Disabled for now
for ( int i = 0; i < 0*items.length; ++i )
{
CreateItemRequest selection = (CreateItemRequest) items[ i ];
int itemId = selection.getItemId();
int maximum = UseItemRequest.maximumUses( itemId, ItemDatabase.getConsumptionType( itemId ) );
int quantityDesired = maximum;
if ( maximum >= 2 )
{
Integer value = InputFieldUtilities.getQuantity(
"Creating " + selection.getName() + " for immediate use...", Math.min( maximum,
selection.getQuantityPossible() + selection.getQuantityPullable() ) );
quantityDesired = ( value == null ) ? 0 : value.intValue();
}
if ( quantityDesired < 1 )
{
continue;
}
KoLmafia.updateDisplay( "Verifying ingredients..." );
int pulled = Math.max( 0, quantityDesired - selection.getQuantityPossible() );
selection.setQuantityNeeded( quantityDesired - pulled );
SpecialOutfit.createImplicitCheckpoint();
RequestThread.postRequest( selection );
SpecialOutfit.restoreImplicitCheckpoint();
if ( pulled > 0 && KoLmafia.permitsContinue() )
{
int newbudget = ConcoctionDatabase.getPullsBudgeted() - pulled;
RequestThread.postRequest( new StorageRequest(
StorageRequest.STORAGE_TO_INVENTORY,
new AdventureResult[] { ItemPool.get( selection.getItemId(), pulled ) } ) );
ConcoctionDatabase.setPullsBudgeted( newbudget );
}
RequestThread.postRequest( UseItemRequest.getInstance( ItemPool.get( selection.getItemId(), quantityDesired ) ) );
}
}
private static class InvSlider
extends JSlider
implements ChangeListener, Listener
{
public InvSlider()
{
super( JSlider.VERTICAL, 0, 30, 18 );
this.setMinorTickSpacing( 1 );
this.setMajorTickSpacing( 5 );
Hashtable h = new Hashtable();
h.put( IntegerPool.get( 0 ), new JLabel( "Free" ) );
h.put( IntegerPool.get( 10 ), new JLabel( "Autosell price" ) );
h.put( IntegerPool.get( 20 ), new JLabel( "Mall (or autosell if min-priced)" ) );
h.put( IntegerPool.get( 30 ), new JLabel( "Mall price" ) );
this.setLabelTable( h );
this.setPaintTicks( true );
this.setSnapToTicks( true );
this.setPaintLabels( true );
this.addChangeListener( this );
PreferenceListenerRegistry.registerPreferenceListener( "valueOfInventory", this );
this.update();
}
public void stateChanged( ChangeEvent e )
{
//if ( this.getValueIsAdjusting() ) return;
Preferences.setFloat( "valueOfInventory", this.getValue() / 10.0f );
}
public void update()
{
this.setValue( (int)
((Preferences.getFloat( "valueOfInventory" ) + 0.05f) * 10.0f) );
}
}
private static class PrefSpinner
extends AutoHighlightSpinner
implements ChangeListener, Listener
{
private String pref;
// This spinner is tied to a Preference.
//
// Since it is a ChangeListener, whenever the user manipulates
// the spinner, the "stateChanged" method is called to change
// the setting, which will write it to the settings file.
//
// Since it is a Listener, whenever the setting
// changes, the "update" method is called to adjust the widget.
//
// We do not want to write the settings file when we are
// adjusting the widget to agree with what the setting has
// already been changed to.
boolean updating = false;
public PrefSpinner( String pref )
{
super();
this.pref = pref;
this.setAlignmentX( 0.0f );
JComponentUtilities.setComponentSize( this, 80, -1 );
// Set the widget from the current value of the setting
this.update();
// Register to be informed when the setting changes
PreferenceListenerRegistry.registerPreferenceListener( pref, this );
// Register to be informed when the widget changes
this.addChangeListener( this );
}
public void stateChanged( ChangeEvent e )
{
// Change the setting to agree with the widget. If we
// are currently loading the widget from the setting,
// do not write the setting.
if ( !updating )
{
int val = InputFieldUtilities.getValue( this, 0 );
Preferences.setInteger( this.pref, val );
}
}
public void update()
{
// Change the widget to agree with the setting
this.updating = true;
this.setValue( Math.max( 0, Preferences.getInteger( this.pref ) ) );
this.updating = false;
}
}
}