/**
 * Copyright (c) 2011, Martin Foster <martin@ethereal-realms.org>
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 * 
 *     * Redistributions of source code must retain the above copyright notice, 
 *       this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of the Ethereal-Realms.org 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 HOLDER 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 org.lyra.Widgets;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.util.Map;

import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

/**
 * Permits the custom application of colours for row and cells generated
 * within a JTable instance.   Used by other renderer's in order to not 
 * require additional complexity and duplication.
 * <p>
 * @author Martin Foster
 * @version 1.0.1, %Revision, 99%, %LastChangedDate, 17/03/11 8:17PM%
 * @see DateTableCellRenderer
 * @see PositionCellRenderer
 */
public class CustomColorRenderer extends DefaultTableCellRenderer {

	// Serial Requirements
	private static final long serialVersionUID = 1L;
	
	// Colour codes
	private Color PrimaryColor;
	private Color SecondaryColor;
	private Color HighlightedColor;
	private Color PrimaryFont;
	private Color HighlightedFont;
	
	// Requirements
	private boolean CustomRender;
	
	// Selected row
	private Integer myCurrent;
	
	/**
	 * Default constructor for the class which will determine the need for
	 * custom colours.  Passes up the colour choices as well as the need
	 * for additional generation.
	 * <p>
	 * @param global Global Map containing colours and user settings.
	 */
	public CustomColorRenderer(Map<String,String> global) {
	
		/*
		 * We pass up the boolean value which will determine the requirement
		 * for a custom renderer or not.
		 */
		CustomRender = Boolean.parseBoolean(global.get("Setting.Interface.Custom"));
		
		
		/*
		 * We pass up the normally expected values for a custom renderer
		 * which are the colours that have been selected by the user.
		 */
		
		// Primary Colour
		PrimaryColor = new Color(
			Integer.parseInt(global.get("Setting.Interface.Color.Row.Primary"))
		  );
		
		// Secondary Colour
		SecondaryColor = new Color(
			Integer.parseInt(global.get("Setting.Interface.Color.Row.Secondary"))
		  );
		
		// Highlighted Colour
		HighlightedColor = new Color(
			Integer.parseInt(global.get("Setting.Interface.Color.Row.Highlight"))
		  );
		
		
		/*
		 * Fonts are an important component of the display of a custom renderer
		 * we cannot make assumptions based on system values, so we can make the
		 * choice here. 
		 */
		
		// Primary Font Selection
		PrimaryFont = new Color(
			Integer.parseInt(global.get("Setting.Interface.Color.Font.Primary"))
		  );
		
		// Highlighted Font Selection
		HighlightedFont = new Color(
			Integer.parseInt(global.get("Setting.Interface.Color.Font.Highlight"))
		  );
		
	}
	// End of Constructor Class
	
	
    /**
     * Allows a certain row to be set as current which means that it will 
     * display more prominently then the others.
     * <p>
     * @param current Integer containing currently selected row.
     */
    public void setActive(Integer current) {
    	
    	// Simply pass up
    	myCurrent = current;
    	
    }
    // End of setPlaying Method
	
	
	/* (non-Javadoc)
	 * @see javax.swing.table.DefaultTableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
	 */
	public Component getTableCellRendererComponent(
		JTable table,
		Object value, 
		boolean selected, 
		boolean focused,
		int row, 
		int column) {
	
		// Extract the Existing Component
		super.getTableCellRendererComponent(
				table, 
				value,
				selected, 
				focused, 
				row, 
				column
			);
		
		
		/*
		 * Due to the nature of certain elements being rendered they may be
		 * a fair bit longer then available.  Hence we use ToolTips to 
		 * allow full view without changing column widths.
		 */
		if (value != null)
			this.setToolTipText(value.toString());
		
		
		/*
		 * This is where we differ from the class which we extend.  Essentially
		 * if we have a currently active row, we will make sure to change
		 * the font in some way in order to determine which is currently
		 * playing.
		 */
		if ((myCurrent != null)
		 && (myCurrent == row)) {

			// Extract Font
			Font copy  = this.getFont();
			
			// Extract individual elements
			float size = copy.getSize();
			
			/*
			 * We essentially take an approach of preference on font visual
			 * changes that we can use to make this happen.
			 */
			
			// If we are not BOLD then we simply BOLD
			if (!copy.isBold())
				this.setFont(
					copy.deriveFont(Font.BOLD));
				
			// If we are BOLD by not ITALIC then we set ITALIC
			else if (!copy.isItalic())
				this.setFont(
					copy.deriveFont(Font.ITALIC));
				
			// Otherwise we increment by one in size
			else
				this.setFont(
					copy.deriveFont((float)(size + 1)));
		}
		
		
		/*
		 * If there is no need to custom generate these elements then there
		 * we will skip the rest of the process.
		 */
		if (!CustomRender)
			return this;

		
		/*
		 * If an element is selected it should show a certain amount of
		 * importance to stand out against the other rows.   This will 
		 * establish the background and foreground colours.
		 */
		if (selected) { 
			
			// Assign highlighted colour
			setBackground(HighlightedColor);
			
			// Assign the appropriate font colour
			setForeground(HighlightedFont);
		}
		
		/*
		 * Elements that are not highlighted will require a bit more processing
		 * to account for alternate and primary row processing.
		 */
		else {
			
			// Adjust based on row element
			Color bg = (row % 2 == 0)
				? SecondaryColor 
				: PrimaryColor;
			
			// Adjust the component
			setBackground(bg);
			
			// Set foreground to primary font colour
			setForeground(PrimaryFont);
		}

		// Return Element
		return this;
	}
	// End of getTableCellRendererComponent Method

}
