/**
* 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.awt.Dimension;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import net.java.dev.spellcast.utilities.LockableListModel;
import net.java.dev.spellcast.utilities.SortedListModel;
import net.sourceforge.kolmafia.AdventureResult;
import net.sourceforge.kolmafia.KoLCharacter;
import net.sourceforge.kolmafia.KoLConstants;
import net.sourceforge.kolmafia.KoLmafia;
import net.sourceforge.kolmafia.RequestThread;
import net.sourceforge.kolmafia.objectpool.ItemPool;
import net.sourceforge.kolmafia.persistence.EquipmentDatabase;
import net.sourceforge.kolmafia.request.PulverizeRequest;
import net.sourceforge.kolmafia.swingui.listener.ThreadedListener;
import net.sourceforge.kolmafia.swingui.widget.AutoFilterTextField;
import net.sourceforge.kolmafia.swingui.widget.ListCellRendererFactory;
import net.sourceforge.kolmafia.textui.command.SendMessageCommand;
import net.sourceforge.kolmafia.utilities.InputFieldUtilities;
public class PulverizePanel
extends ItemListManagePanel
{
private JTable yields;
public PulverizePanel()
{
super( (SortedListModel) KoLConstants.inventory );
this.setButtons( true, new ActionListener[] {
new EnqueueListener(),
new DequeueListener(),
new ClearListener(),
new PulverizeListener(),
new SmashbotListener(),
} );
this.getElementList().setCellRenderer( ListCellRendererFactory.getPulverizationRenderer() );
this.movers[ 2 ].setSelected( true );
}
@Override
public void setEnabled( final boolean isEnabled )
{
super.setEnabled( isEnabled );
if ( this.buttons != null && !KoLCharacter.hasSkill( "Pulverize" ) )
{
this.buttons[ 3 ].setEnabled( false );
}
}
private static class YieldsModel
extends DefaultTableModel
{
private static String[][] contents = new String[][] { {
"P", "2P", "3P",
"<html><center>4P<br>or N</html>",
"<html><center>N+3P<br>or 2N</html>",
"3N",
"<html><center>4N<br>or W</html>",
"<html><center>W+3N<br>or 2W</html>",
"3W",
"1C",
"Other"
} };
public YieldsModel()
{
super( contents, contents[0] );
}
@Override
public boolean isCellEditable( int row, int column )
{
return false;
}
}
@Override
public void addFilters()
{
JPanel filterPanel = new JPanel();
this.filters = new JCheckBox[ 8 ];
this.filters[ 0 ] = new JCheckBox( "twinkly", true );
this.filters[ 1 ] = new JCheckBox( "<html><font color=red>hot</html>", true );
this.filters[ 2 ] = new JCheckBox( "<html><font color=blue>cold</html>", true );
this.filters[ 3 ] = new JCheckBox( "<html><font color=green>stench</html>", true );
this.filters[ 4 ] = new JCheckBox( "<html><font color=gray>spooky</html>", true );
this.filters[ 5 ] = new JCheckBox( "<html><font color=purple>sleaze</html>", true );
this.filters[ 6 ] = new JCheckBox( "Smiths", true );
this.filters[ 7 ] = new JCheckBox( "other" );
for ( int i = 0; i < 8; ++i )
{
filterPanel.add( this.filters[ i ] );
this.listenToCheckBox( this.filters[ i ] );
}
this.northPanel.add( filterPanel, BorderLayout.NORTH );
this.yields = new JTable( new YieldsModel() );
this.yields.setTableHeader( null );
this.yields.setShowVerticalLines( true );
this.yields.setSelectionMode( ListSelectionModel.SINGLE_INTERVAL_SELECTION );
this.yields.setCellSelectionEnabled( true );
this.yields.selectAll();
DefaultTableCellRenderer tcr = new DefaultTableCellRenderer();
tcr.setHorizontalAlignment( DefaultTableCellRenderer.CENTER );
this.yields.setDefaultRenderer( Object.class, tcr );
Dimension dims = tcr.getTableCellRendererComponent( this.yields,
"<html> W+3N <br> N+3P </html>",
false, false, 0, 0 ).getPreferredSize();
this.yields.setRowHeight( dims.height );
dims.width *= 9;
this.yields.setPreferredScrollableViewportSize( dims );
this.yields.setToolTipText( "Drag to select a range of yields. " +
"P = powder, N = nugget, W = wad, C = cluster." );
this.yields.getColumnModel().getSelectionModel().addListSelectionListener(
(ListSelectionListener) this.filterfield );
// If the yields list was added directly to northPanel, it would get horizontally
// stretched, creating useless blank space inside the list frame. Having an
// intermediate JPanel, with the default FlowLayout, allows the list to take on its
// natural width.
JPanel panel = new JPanel();
panel.add( new JScrollPane( this.yields,
JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER ) );
this.northPanel.add( panel, BorderLayout.CENTER );
this.filterItems();
}
@Override
public AutoFilterTextField getWordFilter()
{
return new EquipmentFilterField();
}
private class EquipmentFilterField
extends AutoFilterTextField
implements ListSelectionListener
{
boolean others = false;
boolean smiths = false;
int elemMask = 0;
int yieldMask = 0;
public EquipmentFilterField()
{
super( PulverizePanel.this.getElementList() );
}
public void valueChanged( ListSelectionEvent e )
{
this.update();
}
@Override
public synchronized void update()
{
this.smiths = PulverizePanel.this.filters[ 6 ].isSelected();
this.others = PulverizePanel.this.filters[ 7 ].isSelected();
this.elemMask =
(PulverizePanel.this.filters[ 0 ].isSelected() ?
EquipmentDatabase.ELEM_TWINKLY : 0) |
(PulverizePanel.this.filters[ 1 ].isSelected() ?
EquipmentDatabase.ELEM_HOT : 0) |
(PulverizePanel.this.filters[ 2 ].isSelected() ?
EquipmentDatabase.ELEM_COLD : 0) |
(PulverizePanel.this.filters[ 3 ].isSelected() ?
EquipmentDatabase.ELEM_STENCH : 0) |
(PulverizePanel.this.filters[ 4 ].isSelected() ?
EquipmentDatabase.ELEM_SPOOKY : 0) |
(PulverizePanel.this.filters[ 5 ].isSelected() ?
EquipmentDatabase.ELEM_SLEAZE : 0) |
(this.others ? EquipmentDatabase.ELEM_OTHER : 0);
this.yieldMask = 0;
int[] indices = PulverizePanel.this.yields.getSelectedColumns();
for ( int i = 0; i < indices.length; ++i )
{
this.yieldMask |= EquipmentDatabase.YIELD_1P << indices[ i ];
}
super.update();
}
@Override
public boolean isVisible( final Object element )
{
if ( element == null || !(element instanceof AdventureResult) )
{
return false;
}
boolean isVisibleWithFilter = true;
int itemId = ( (AdventureResult) element ).getItemId();
if ( itemId == -1 )
{
return false;
}
int pulver = EquipmentDatabase.getPulverization( itemId );
if ( pulver == -1 )
{
return false;
}
if ( pulver == ItemPool.HANDFUL_OF_SMITHEREENS )
{
isVisibleWithFilter = this.smiths && this.yieldMask >= 2048;
}
else if ( pulver >= 0 )
{
isVisibleWithFilter = this.others && this.yieldMask >= 2048;
}
else
{
isVisibleWithFilter = ( pulver & this.elemMask ) != 0 &&
( pulver & this.yieldMask ) != 0;
}
return isVisibleWithFilter && super.isVisible( element );
}
}
public class EnqueueListener
extends TransferListener
{
public EnqueueListener()
{
super( "Smashing", false );
}
@Override
protected void execute()
{
Object[] items = this.initialSetup();
if ( items == null || items.length == 0 )
{
return;
}
for ( int i = 0; i < items.length; ++i )
{
AdventureResult item = (AdventureResult) items[ i ];
if ( item.getCount() > 0 )
{
KoLConstants.pulverizeQueue.remove( item );
KoLConstants.pulverizeQueue.add( item );
LockableListModel inv = (LockableListModel)
PulverizePanel.this.getElementList().getModel();
int index = inv.indexOf( item );
inv.fireContentsChanged( inv, index, index );
}
}
}
@Override
public String toString()
{
return "add to queue";
}
}
public class DequeueListener
extends TransferListener
{
public DequeueListener()
{
super( "Keeping", false );
}
@Override
protected void execute()
{
Object[] items = this.initialSetup( ItemManagePanel.TAKE_ALL );
if ( items == null || items.length == 0 )
{
return;
}
for ( int i = 0; i < items.length; ++i )
{
AdventureResult item = (AdventureResult) items[ i ];
if ( item.getCount() > 0 )
{
KoLConstants.pulverizeQueue.remove( item );
LockableListModel inv = (LockableListModel)
PulverizePanel.this.getElementList().getModel();
int index = inv.indexOf( item );
inv.fireContentsChanged( inv, index, index );
}
}
}
@Override
public String toString()
{
return "remove from queue";
}
}
public class ClearListener
extends ThreadedListener
{
@Override
protected void execute()
{
KoLConstants.pulverizeQueue.clear();
LockableListModel inv = (LockableListModel)
PulverizePanel.this.getElementList().getModel();
inv.fireContentsChanged( inv, 0, inv.size() - 1 );
}
@Override
public String toString()
{
return "clear queue";
}
}
public class PulverizeListener
extends ThreadedListener
{
@Override
protected void execute()
{
if ( KoLConstants.pulverizeQueue.isEmpty() )
{
(new EnqueueListener()).run();
if ( KoLConstants.pulverizeQueue.isEmpty() )
{
InputFieldUtilities.alert( "No items selected or in queue!" );
return;
}
}
AdventureResult[] items =
new AdventureResult[ KoLConstants.pulverizeQueue.size() ];
KoLConstants.pulverizeQueue.toArray( items );
KoLConstants.pulverizeQueue.clear();
LockableListModel inv = (LockableListModel)
PulverizePanel.this.getElementList().getModel();
inv.fireContentsChanged( inv, 0, inv.size() - 1 );
for ( int i = 0; i < items.length; ++i )
{
RequestThread.postRequest( new PulverizeRequest( items[ i ] ) );
}
}
@Override
public String toString()
{
return "pulverize";
}
}
private static class MsgOption
{
private String asString;
private String asMessage;
public MsgOption( String asString, String asMessage )
{
this.asString = asString;
this.asMessage = asMessage;
}
@Override
public String toString()
{
return this.asString;
}
public String toMessage()
{
return this.asMessage;
}
}
public class SmashbotListener
extends ThreadedListener
{
@Override
protected void execute()
{
if ( KoLConstants.pulverizeQueue.isEmpty() )
{
InputFieldUtilities.alert( "No items in queue!" );
return;
}
String message;
if ( KoLmafia.isPlayerOnline( "smashbot" ) )
{ // bot online
if ( KoLCharacter.canInteract() )
{
message = "Smashbot is online, and ready to SMASH!";
}
else
{
InputFieldUtilities.alert( "Smashbot is online, but won't play with you in hardcore or ronin!" );
return;
}
}
else
{ // bot offline
if ( KoLCharacter.canInteract() )
{
message = "Smashbot is offline, so there will be a delay before you receive your smashed items. Are you sure you want to continue?";
}
else
{
InputFieldUtilities.alert( "Smashbot won't play with you in hardcore or ronin. Smashbot isn't online, anyway." );
return;
}
}
MsgOption selected = (MsgOption) InputFieldUtilities.input( message,
new MsgOption[] {
new MsgOption( "receive results as is", "" ),
new MsgOption( "powders -> nuggets", "nuggets" ),
new MsgOption( "also nuggets -> wads", "wads" ),
}, null );
if ( selected == null )
{
return;
}
AdventureResult[] items =
new AdventureResult[ KoLConstants.pulverizeQueue.size() ];
KoLConstants.pulverizeQueue.toArray( items );
KoLConstants.pulverizeQueue.clear();
LockableListModel inv = (LockableListModel)
PulverizePanel.this.getElementList().getModel();
inv.fireContentsChanged( inv, 0, inv.size() - 1 );
SendMessageCommand.send( "smashbot", selected.toMessage(),
items, false, true );
}
@Override
public String toString()
{
return "send to smashbot";
}
}
}