package de.javasoft.synthetica.democenter.examples.monthview;

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.util.Calendar;
import java.util.Date;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;

import org.jdesktop.swingx.JXMonthView;
import org.jdesktop.swingx.calendar.DateSelectionModel.SelectionMode;
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.jdesktop.swingx.decorator.ComponentAdapter;
import org.jdesktop.swingx.decorator.CompoundHighlighter;
import org.jdesktop.swingx.decorator.HighlightPredicate;
import org.jdesktop.swingx.decorator.Highlighter;
import org.jdesktop.swingx.plaf.basic.CalendarRenderingHandler;
import org.jdesktop.swingx.plaf.basic.CalendarState;
import org.jdesktop.swingx.plaf.basic.PublicCalendarRenderingHandler;
import org.jdesktop.swingx.plaf.basic.PublicCalendarRenderingHandler.MonthViewCalendarAdapter;

import de.javasoft.plaf.synthetica.MonthViewUI;
import de.javasoft.swing.DateComboBox;
import de.javasoft.swing.plaf.datecombobox.DateComboBoxMonthView;
import de.javasoft.swing.plaf.datecombobox.DateComboBoxPopup;
import de.javasoft.swing.plaf.datecombobox.DateComboBoxUI;
import de.javasoft.synthetica.addons.highlighter.ColorTextHighlighter;

//SwingX 1.6.5 required

@SuppressWarnings("serial")
public class MonthViewHighlighterTest extends JFrame
{
  
  public MonthViewHighlighterTest()
  {
    super("Simple MonthView");
    // create and add the hyperlinkpanel
    JPanel panel = new JPanel();
    panel.setBorder(new EmptyBorder(10, 10, 10, 10));
    //panel.setBackground(Color.WHITE);
    createAndAddComponents(panel);
    add(panel);

    setTitle(getClass().getSimpleName());
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(400, 300);
    setLocationRelativeTo(null); // center
    setVisible(true);
  }

  /**
   * Creates components and adds them the panel.
   */
  private void createAndAddComponents(JPanel panel)
  {
    JXMonthView mv = new JXMonthView();
    mv.setName("MyMonthView");
    //mv.setFirstDisplayedDay(cal.getTime());
    /*mv.setUI(new MonthViewUI(){
      @Override
      protected CalendarRenderingHandler createRenderingHandler()
      {
        PublicCalendarRenderingHandler handler = new PublicCalendarRenderingHandler();
        HighlightPredicate predicate = new HighlightPredicate()
        {          
          @Override
          public boolean isHighlighted(Component renderer, ComponentAdapter adapter)
          {
            System.err.println(renderer);
            System.err.println(adapter);
            return true;
          }
        };
        handler.setHighlighters(new ColorHighlighter(predicate, Color.RED, Color.YELLOW));
        return handler;
      }
    });*/
    //show month up/down arrows

    configurMonthView(mv);
    panel.add(mv);
    
    final DateComboBox combo = new DateComboBox(){
      @Override
      public void updateUI()
      {
        if (getPopup() != null)
          getPopup().updateUI();
        setUI(new DateComboBoxUI(){
          @Override
          protected DateComboBoxPopup createDateComboBoxPopup(DateComboBox combo)
          {
            return new DateComboBoxPopup(combo){
              @Override
              protected DateComboBoxMonthView createMonthView(DateComboBox dateComboBox)
              {
                //return super.createMonthView(dateComboBox);
                DateComboBoxMonthView monthView = new DateComboBoxMonthView(dateComboBox, this){
                  @Override
                  public void updateUI() 
                  {
                    setUI(new MonthViewUI(){
                      @Override
                      protected CalendarRenderingHandler createRenderingHandler()
                      {
                        //CalendarRenderingHandler renderer = super.createRenderingHandler();
                        PublicCalendarRenderingHandler renderer = new PublicCalendarRenderingHandler();
                        renderer.setHighlighters(createHighlighter());                        
                        return renderer;
                      }
                    });
                  }
                };
                configurMonthView(monthView);
                return monthView;
              }
            };
          }
        });
      }
    };

    
     /*DateComboBox combo = new DateComboBox(){      
       @Override
       public DateComboBoxMonthView createMonthView()
       {
         //return super.createMonthView(dateComboBox);
         DateComboBoxMonthView monthView = new DateComboBoxMonthView(this, getPopup());
         monthView.setShowingWeekNumber(true);
         monthView.setShowingLeadingDays(true);
         monthView.setShowingTrailingDays(true);
         monthView.setDayForeground(Calendar.SATURDAY, new Color(0x40A020));
         monthView.setDayForeground(Calendar.SUNDAY, new Color(0x40A020));
         return monthView;
       }
    }; */   
    
//    combo.getPopup().getMonthView()
    
    panel.add(combo);
  }

  
  private Highlighter createHighlighter()
  {
    CompoundHighlighter highlighter = new CompoundHighlighter();
    /*HighlightPredicate boldPredicate = new HighlightPredicate()
    {
      public boolean isHighlighted(Component renderer, ComponentAdapter adapter)
      {
        if (!(adapter instanceof PublicCalendarAdapter))
          return false;
        PublicCalendarAdapter ca = (PublicCalendarAdapter) adapter;
        return CalendarState.DAY_OF_WEEK == ca.getCalendarState() || CalendarState.TITLE == ca.getCalendarState();
      }
    };
    
    Highlighter font = new AbstractHighlighter(boldPredicate)
    {
      @Override
      protected Component doHighlight(Component component, ComponentAdapter adapter)
      {
        //component.setFont(getDerivedFont(component.getFont()));
        return component;
      }
    };
    highlighter.addHighlighter(font);*/

    //set unselectable foreground same as leadingDayForeground
    HighlightPredicate unselectable = new HighlightPredicate()
    {
      public boolean isHighlighted(Component renderer, ComponentAdapter adapter)
      {
        if (!(adapter instanceof MonthViewCalendarAdapter))
          return false;
        return ((MonthViewCalendarAdapter) adapter).isUnselectable();
      }
    };
    //transparent background color disables the red cross
    ColorTextHighlighter unselectableHL = new ColorTextHighlighter(unselectable, new Color(0,0,0,0), UIManager.getColor("JXMonthView.leadingDayForeground")); //see MonthViewAddon    
    highlighter.addHighlighter(unselectableHL);
    
    HighlightPredicate weekend = new HighlightPredicate()
    {
      public boolean isHighlighted(Component renderer, ComponentAdapter adapter)
      {
        if (!(adapter instanceof MonthViewCalendarAdapter))
          return false;
        return ((MonthViewCalendarAdapter) adapter).isWeekend();
      }
    };
    ColorTextHighlighter weekendHL = new ColorTextHighlighter(weekend, Color.CYAN, null);
    highlighter.addHighlighter(weekendHL);
    
    HighlightPredicate flagged = new HighlightPredicate()
    {
      public boolean isHighlighted(Component renderer, ComponentAdapter adapter)
      {
        if (!(adapter instanceof MonthViewCalendarAdapter) || CalendarState.IN_MONTH != ((MonthViewCalendarAdapter)adapter).getCalendarState())
          return false;
        return ((MonthViewCalendarAdapter) adapter).isFlagged();
      }
    };
    ColorTextHighlighter flaggedHL = new ColorTextHighlighter(flagged, Color.RED, Color.WHITE, Color.RED, Color.WHITE);
    highlighter.addHighlighter(flaggedHL);
    
    HighlightPredicate marked = new HighlightPredicate()
    {
      public boolean isHighlighted(Component renderer, ComponentAdapter adapter)
      {
        if (!(adapter instanceof MonthViewCalendarAdapter) || CalendarState.IN_MONTH != ((MonthViewCalendarAdapter)adapter).getCalendarState())
          return false;
        Calendar cal = Calendar.getInstance();
        cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, 20);
        cal.set(Calendar.HOUR, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);        
        cal.set(Calendar.AM_PM, Calendar.AM);
        Calendar cal2 = (Calendar)cal.clone();
        cal2.set(Calendar.DAY_OF_MONTH, 22);
        Date d = ((MonthViewCalendarAdapter) adapter).getCalendar().getTime(); 
        return d.equals(cal.getTime()) || d.equals(cal2.getTime()) ; // && !((PublicCalendarAdapter) adapter).isSelected();
      }
    };
    /*markedBackgroundPainter.setColor(Color.MAGENTA);
    Highlighter markedBackgroundHL = new PainterHighlighter(marked, markedBackgroundPainter);
    highlighter.addHighlighter(markedBackgroundHL);
    ColorHighlighter markedForegroundHL = new ColorHighlighter(marked, new Color(0,0,0,0), Color.WHITE);
    markedForegroundHL.setSelectedForeground(Color.WHITE);
    highlighter.addHighlighter(markedForegroundHL); */
    //TextColorHighlighter markedHL = new TextColorHighlighter(marked, Color.MAGENTA, Color.WHITE, Color.BLUE, Color.RED);
    ColorTextHighlighter markedHL = new ColorTextHighlighter(marked, Color.MAGENTA, Color.WHITE);
    highlighter.addHighlighter(markedHL);

    //week of year foreground gray
    HighlightPredicate week = new HighlightPredicate()
    {
      public boolean isHighlighted(Component renderer, ComponentAdapter adapter)
      {
        return (adapter instanceof MonthViewCalendarAdapter && CalendarState.WEEK_OF_YEAR == ((MonthViewCalendarAdapter)adapter).getCalendarState()) ? true : false;
      }
    };
    ColorHighlighter weekHL = new ColorHighlighter(week, null, Color.LIGHT_GRAY);
    highlighter.addHighlighter(weekHL);
    
    //foreground setting - see CalendarCellContext#getSelectionForeground(), CalendarCellContext#getForeground(), DefaultVisuals#configureColors()
    return highlighter;
  }  
  
  private void configurMonthView(JXMonthView mv)
  {
    /*mv.setSelectionModel(new DefaultDateSelectionModel(){
      @Override
      public boolean isUnselectableDate(Date date)
      {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        Calendar now = Calendar.getInstance();
        now.set(Calendar.HOUR, 0);
        now.set(Calendar.MINUTE, 0);
        now.set(Calendar.SECOND, 0);
        now.set(Calendar.MILLISECOND, 0);
        now.set(Calendar.AM_PM, Calendar.AM);
        return cal.before(now);
        //super.isUnselectableDate(date);
      }
    });*/
    
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.DAY_OF_MONTH, 2);
    Calendar cal2 = Calendar.getInstance();
    cal2.set(Calendar.DAY_OF_MONTH, 3);
    Calendar cal3 = Calendar.getInstance();
    cal3.set(Calendar.DAY_OF_MONTH, 4);
    mv.setUnselectableDates(cal.getTime(), cal2.getTime(), cal3.getTime());
    
    mv.setTraversable(true);
    mv.setShowingLeadingDays(true);
    mv.setShowingTrailingDays(true);
    mv.setShowingWeekNumber(true);
    mv.setDayForeground(Calendar.SATURDAY, new Color(0xE04020));
    mv.setDayForeground(Calendar.SUNDAY, new Color(0xE04020));
        
    //mv.setSelectionMode(SelectionMode.SINGLE_SELECTION);
    mv.setSelectionMode(SelectionMode.SINGLE_INTERVAL_SELECTION);
    //mv1.setSelectionMode(SelectionMode.MULTIPLE_INTERVAL_SELECTION);
    //mv.setPreferredRowCount(3);
    
    // Create some dates that we want to flag as being important.
    cal = Calendar.getInstance();
    cal.set(Calendar.DAY_OF_MONTH, 25);
    mv.setFlaggedDayForeground(Color.GREEN);
    mv.setFlaggedDates(cal.getTime());
    
    /*Calendar cal4 = Calendar.getInstance();
    cal4.set(Calendar.DAY_OF_MONTH, 2);
    Calendar cal6 = Calendar.getInstance();
    cal6.set(Calendar.DAY_OF_MONTH, 16);
    Calendar cal5 = Calendar.getInstance();
    cal5.set(Calendar.DAY_OF_MONTH, 29);
    mv.setFlaggedDates(cal4.getTime(), cal5.getTime(), cal6.getTime());*/
  }
  
  /**
   * Static main method for application startup.
   */
  public static void main(String[] args)
  {
    EventQueue.invokeLater(new Runnable()
    {
      public void run()
      {
        try
        {
          UIManager.setLookAndFeel("de.javasoft.plaf.synthetica.SyntheticaStandardLookAndFeel");
          //UIManager.setLookAndFeel("de.javasoft.plaf.synthetica.SyntheticaBlueLightLookAndFeel");
          //UIManager.setLookAndFeel("de.javasoft.plaf.synthetica.SyntheticaAluOxideLookAndFeel");
          //UIManager.setLookAndFeel("de.javasoft.plaf.synthetica.SyntheticaBlackEyeLookAndFeel");
          //UIManager.put("Synthetica.monthView.opaqueDayHighlighterSupport.MyMonthView", true);
          new MonthViewHighlighterTest();
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
      }
    });
  }
}

