1 /*
   2  * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.javafx.scene.control.skin;
  27 
  28 import java.time.LocalDate;
  29 import java.time.DateTimeException;
  30 import java.time.YearMonth;
  31 import java.time.format.DecimalStyle;
  32 import java.time.chrono.Chronology;
  33 import java.time.chrono.HijrahChronology;
  34 import java.time.chrono.HijrahDate;
  35 import java.time.chrono.IsoChronology;
  36 import java.util.Locale;
  37 
  38 import static java.time.temporal.ChronoField.*;
  39 
  40 import javafx.geometry.Pos;
  41 import javafx.scene.control.DatePicker;
  42 import javafx.scene.control.DateCell;
  43 import javafx.scene.control.Label;
  44 import javafx.scene.layout.BorderPane;
  45 import javafx.scene.text.Text;
  46 
  47 /**
  48  * Extends DatePickerContent to add a secondary calendar, allowing the
  49  * ISO and Islamic calendars to be displayed simultaneously.  The
  50  * secondary month, day, and year values are displayed as a colored
  51  * overlay, offset from the primary values.
  52  *
  53  * If the current DatePicker Chronology is HijrahChronology, then sets
  54  * the content's primary Chronology to be IsoChronology, and sets
  55  * HijrahChronology as the secondary.
  56  */
  57 class DatePickerHijrahContent extends DatePickerContent {
  58     private Label hijrahMonthYearLabel;
  59 
  60     DatePickerHijrahContent(final DatePicker datePicker) {
  61         super(datePicker);
  62     }
  63 
  64     /**
  65      * The primary chronology for display. This is overridden because
  66      * DatePickerHijrahContent uses ISO as primary and Hijrah as a
  67      * secondary chronology.
  68      */
  69     @Override protected Chronology getPrimaryChronology() {
  70         return IsoChronology.INSTANCE;
  71     }
  72 
  73     @Override protected BorderPane createMonthYearPane() {
  74         BorderPane monthYearPane = super.createMonthYearPane();
  75 
  76         hijrahMonthYearLabel = new Label();
  77         hijrahMonthYearLabel.getStyleClass().add("secondary-label");
  78         monthYearPane.setBottom(hijrahMonthYearLabel);
  79         BorderPane.setAlignment(hijrahMonthYearLabel, Pos.CENTER);
  80 
  81         return monthYearPane;
  82     }
  83 
  84 
  85     @Override protected void updateMonthYearPane() {
  86         super.updateMonthYearPane();
  87 
  88         Locale locale = getLocale();
  89         HijrahChronology chrono = HijrahChronology.INSTANCE;
  90         long firstMonth = -1;
  91         long firstYear = -1;
  92         String firstMonthStr = null;
  93         String firstYearStr = null;
  94         String hijrahStr = null;
  95         YearMonth displayedYearMonth = displayedYearMonthProperty().get();
  96 
  97         for (DateCell dayCell : dayCells) {
  98             LocalDate date = dayCellDate(dayCell);
  99 
 100             // Display Hijra month names only for current ISO month.
 101             if (!displayedYearMonth.equals(YearMonth.from(date))) {
 102                 continue;
 103             }
 104 
 105             try {
 106                 HijrahDate cDate = chrono.date(date);
 107                 long month = cDate.getLong(MONTH_OF_YEAR);
 108                 long year = cDate.getLong(YEAR);
 109 
 110                 if (hijrahStr == null || month != firstMonth) {
 111                     String monthStr = monthFormatter.withLocale(locale)
 112                                                     .withChronology(chrono)
 113                                                     .withDecimalStyle(DecimalStyle.of(locale))
 114                                                     .format(cDate);
 115                     String yearStr = yearFormatter.withLocale(locale)
 116                                                     .withChronology(chrono)
 117                                                     .withDecimalStyle(DecimalStyle.of(locale))
 118                                                     .format(cDate);
 119                     if (hijrahStr == null) {
 120                         firstMonth = month;
 121                         firstYear = year;
 122                         firstMonthStr = monthStr;
 123                         firstYearStr = yearStr;
 124                         hijrahStr = firstMonthStr + " " + firstYearStr;
 125                     } else {
 126                         if (year > firstYear) {
 127                             hijrahStr = firstMonthStr + " " + firstYearStr + " - " + monthStr + " " + yearStr;
 128                         } else {
 129                             hijrahStr = firstMonthStr + " - " + monthStr + " " + firstYearStr;
 130                         }
 131                         break;
 132                     }
 133                 }
 134             } catch (DateTimeException ex) {
 135                 // Date is out of range, ignore.
 136 
 137                 //System.err.println(dayCellDate(dayCell) + " " + ex);
 138             }
 139         }
 140 
 141         hijrahMonthYearLabel.setText(hijrahStr);
 142     }
 143 
 144     @Override protected void createDayCells() {
 145         super.createDayCells();
 146 
 147         for (DateCell dayCell : dayCells) {
 148             Text secondaryText = new Text();
 149             dayCell.getProperties().put("DateCell.secondaryText", secondaryText);
 150         }
 151     }
 152 
 153     @Override void updateDayCells() {
 154         super.updateDayCells();
 155 
 156         Locale locale = getLocale();
 157         HijrahChronology chrono = HijrahChronology.INSTANCE;
 158 
 159         int majorityMonth = -1;
 160         int visibleDaysInMajorityMonth = -1;
 161         int curMonth = -1;
 162         int visibleDaysInCurMonth = 0;
 163 
 164         for (DateCell dayCell : dayCells) {
 165             Text secondaryText = (Text)dayCell.getProperties().get("DateCell.secondaryText");
 166             dayCell.getStyleClass().add("hijrah-day-cell");
 167             secondaryText.getStyleClass().setAll("text", "secondary-text");
 168 
 169             try {
 170                 HijrahDate cDate = chrono.date(dayCellDate(dayCell));
 171 //             long month = cDate.getLong(MONTH_OF_YEAR);
 172 
 173                 String hijrahStr =
 174                     dayCellFormatter.withLocale(locale)
 175                                     .withChronology(chrono)
 176                                     .withDecimalStyle(DecimalStyle.of(locale))
 177                                     .format(cDate);
 178 
 179                 secondaryText.setText(hijrahStr);
 180                 dayCell.requestLayout();
 181             } catch (DateTimeException ex) {
 182                 // Date is out of range.
 183                 // System.err.println(dayCellDate(dayCell) + " " + ex);
 184                 secondaryText.setText(" ");
 185                 dayCell.setDisable(true);
 186             }
 187 
 188 //             if (month == curMonth) {
 189 //                 visibleDaysInCurMonth++;
 190 //             } else {
 191 //                 curMonth = month;
 192 //                 visibleDaysInCurMonth = 1;
 193 //             }
 194 //             if (visibleDaysInCurMonth > visibleDaysInMajorityMonth) {
 195 //                 majorityMonth = month;
 196 //                 visibleDaysInMajorityMonth = visibleDaysInCurMonth;
 197 //             }
 198         }
 199 
 200 //         boolean seenMajorityMonth = false;
 201 //         for (DateCell dayCell : dayCells) {
 202 //             HijrahDate cDate = chrono.date(dayCellDate(dayCell));
 203 //             int month = cDate.get(MONTH_OF_YEAR);
 204 //             Text secondaryText = (Text)dayCell.getProperties().get("DateCell.secondaryText");
 205 
 206 //             if (month == majorityMonth) {
 207 //                 seenMajorityMonth = true;
 208 //                 secondaryText.getStyleClass().add("current-month");
 209 //             } else {
 210 //                 secondaryText.getStyleClass().add(seenMajorityMonth ? "next-month" : "previous-month");
 211 //             }
 212 //         }
 213     }
 214 }