/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package clips.analysis.shedule;
import clips.delegate.directory.filtered.DirectoryCheckupTypeItem;
import clips.delegate.doctor.checkup.CheckupLocal;
import clips.delegate.doctor.checkup.shedule.CheckupSheduleLocal;
import cli_fmw.main.ClipsException;
import cli_fmw.delegate.utils.TimeLocal;
import cli_fmw.utils.ErrorValue;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.swing.table.AbstractTableModel;
/**
*
* @author vip
*/
public class TableModelAnalyseShedule extends AbstractTableModel {
public static final int COL_COUNT = 4;
public static final int COL_TYPE = 0;
public static final int COL_WORK_LIFE = 1;
public static final int COL_OUT_SHEDULE = 2;
public static final int COL_IN_SHEDULE = 3;
public static final int DAYS = 10; //количество дней в расписании
private Map<DirectoryCheckupTypeItem, ArrayList<CheckupLocal>> checkupMapFree
= new HashMap<DirectoryCheckupTypeItem, ArrayList<CheckupLocal>>();//Список чекапов не в расписании
private Map<DirectoryCheckupTypeItem, ArrayList<CheckupSheduleLocal>> sheduleMap
= new HashMap<DirectoryCheckupTypeItem, ArrayList<CheckupSheduleLocal>>();
private Map<DirectoryCheckupTypeItem, Date> workLifeMap
= new HashMap<DirectoryCheckupTypeItem, Date>(); //Ближайшие сроки годности для типов
private ArrayList<DirectoryCheckupTypeItem> typeList; //все возможные типы анализов
private Date current; //Начальная дата расписания
public TableModelAnalyseShedule(Map<DirectoryCheckupTypeItem, ArrayList<CheckupLocal>> checkupMap,
ArrayList<CheckupSheduleLocal> checkUpSheduleLocalList)
throws ClipsException {
//Заполним мап списками шедулей
for (CheckupSheduleLocal shedule : checkUpSheduleLocalList) {
if (sheduleMap.get(shedule.getType()) == null) {
sheduleMap.put(shedule.getType(), new ArrayList<CheckupSheduleLocal>());
}
sheduleMap.get(shedule.getType()).add(shedule);
}
Set<DirectoryCheckupTypeItem> typeSet = sheduleMap.keySet();
//Предварительные вычисления и заполнения массивов
//заполнение типов
typeList = new ArrayList<DirectoryCheckupTypeItem>();
//Этот бубен нужен для добавления типов свободных чекапов
//тк жава неспособна добавлять элемент самописного класса в сет того же класса
//(или я чего та не понял)
Iterator<DirectoryCheckupTypeItem> iter = checkupMap.keySet().iterator();
while (iter.hasNext()) {
DirectoryCheckupTypeItem item = iter.next();
if (!typeSet.contains(item)) {
typeList.add(item);
}
}
//вычисление начальной даты
GregorianCalendar gc = TimeLocal.getCurrentTime();
gc = new GregorianCalendar(gc.get(GregorianCalendar.YEAR),
gc.get(GregorianCalendar.MONTH),
gc.get(GregorianCalendar.DAY_OF_MONTH));
current = gc.getTime();
this.checkupMapFree = checkupMap;
Iterator<DirectoryCheckupTypeItem> ti = typeList.iterator();
while (ti.hasNext()) {
DirectoryCheckupTypeItem type = ti.next();
if (checkupMapFree.get(type) == null) {
checkupMapFree.put(type, new ArrayList<CheckupLocal>());
}
}
Iterator<DirectoryCheckupTypeItem> it = typeSet.iterator();
while (it.hasNext()) {
DirectoryCheckupTypeItem item = it.next();
typeList.add(item);
}
it = typeList.iterator();
while (it.hasNext()) {
DirectoryCheckupTypeItem item = it.next();
//найдём минимальный срок годности для типа
Date minWLDate = null;
if (checkupMapFree.get(item) != null) {
for (CheckupLocal cl : checkupMapFree.get(item)) {
if (minWLDate == null) {
minWLDate = cl.getWorkingLifeDate();
} else if (cl.getDate() != null) {
if (cl.getWorkingLifeDate().before(minWLDate)) {
minWLDate = cl.getWorkingLifeDate();
}
}
}
}
if (sheduleMap.get(item) != null) {
for (CheckupSheduleLocal csl : sheduleMap.get(item)) {
Iterator<CheckupLocal> chi = csl.getCheckupSet().iterator();
while (chi.hasNext()) {
CheckupLocal cl = chi.next();
if (minWLDate == null) {
minWLDate = cl.getWorkingLifeDate();
} else if (cl.getDate() != null) {
if (cl.getWorkingLifeDate().before(minWLDate)) {
minWLDate = cl.getWorkingLifeDate();
}
}
}
}
}
workLifeMap.put(item, minWLDate);//положим его в мап
}
}
@Override
public int getRowCount() {
return typeList.size();
}
@Override
public int getColumnCount() {
return COL_COUNT + DAYS;
}
@Override
public String getColumnName(int col) {
if (col == COL_TYPE) {
return "Тип анализа";
} else if (col == COL_WORK_LIFE) {
return "Ближ. срок годности";
} else if (col == COL_OUT_SHEDULE) {
return "Не в распис.";
} else if (col == COL_IN_SHEDULE) {
return "В распис.";
} else {
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM");
return formatter.format(getDateAt(col));
}
}
public Object getValueAt(int row, int col) {
DirectoryCheckupTypeItem type = typeList.get(row);
try {
if (col == COL_TYPE) {
return type;
} else if (col == COL_WORK_LIFE) {
//дата ближайшего срока годности
return workLifeMap.get(type);
} else if (col == COL_OUT_SHEDULE) {
//вычисляем сколько свободных чекапов совпадает по типу с данной строкой
return checkupMapFree.get(type) == null ? 0 : checkupMapFree.get(type).size();
} else if (col == COL_IN_SHEDULE) {
/*вычисляем суммарное число чекапов находящееся во всех элементах
* расписания данного типа
*/
int inSedule = 0;
if (sheduleMap.get(type) != null) {
for (int i = 0; i < sheduleMap.get(type).size(); i++) {
inSedule += sheduleMap.get(type).get(i).getCheckupSet().size();
}
}
return inSedule;
} else {
/*Вычисляем сколько чекапов находятся в элементе расписания данного
типа, приходящееся на данную дату
*/
CheckupSheduleLocal shedule = getSheduleAt(row, col);
if (shedule != null) {
int size = shedule.getCheckupSet() != null
? shedule.getCheckupSet().size() : 0;
return size == 0 ? null : size;
} else {
return null;
}
}
} catch (ClipsException ex) {
return new ErrorValue(ex);
}
}
/**
* Возвращает элемент расписания анализов, находящийся в заданной ячейке
* таблицы. Если такой элемент не существует вернет null
* @param row
* @param col
* @return
*/
public CheckupSheduleLocal getSheduleAt(int row, int col) throws ClipsException {
if (col < COL_COUNT) {
return null;
}
GregorianCalendar gcCell = new GregorianCalendar();
gcCell.setTime(getDateAt(col));
CheckupSheduleLocal founded = null;
if (sheduleMap.get(typeList.get(row)) != null) {
for (CheckupSheduleLocal shedule : sheduleMap.get(typeList.get(row))) {
GregorianCalendar gcShedule = new GregorianCalendar();
gcShedule.setTime(shedule.getDate());
if (gcShedule.get(GregorianCalendar.YEAR) ==
gcCell.get(GregorianCalendar.YEAR) &&
gcShedule.get(GregorianCalendar.DAY_OF_YEAR) ==
gcCell.get(GregorianCalendar.DAY_OF_YEAR)) {
founded = shedule;
break;
}
}
}
return founded;
}
/**
* Тип чекапа в данной строке.
* @param row
* @return
*/
public DirectoryCheckupTypeItem getCheckUpTypeAt(int row) {
return typeList.get(row);
}
/**
* Возвращает дату, соответствующую данному столбцу
* @param col
* @return
*/
public Date getDateAt(int col) {
if (col >= COL_COUNT) {
int day = col - COL_COUNT;
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(current);
gc.add(GregorianCalendar.DAY_OF_YEAR, day);
return gc.getTime();
} else {
return null;
}
}
}