/* This file is part of JFLICKS. JFLICKS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. JFLICKS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with JFLICKS. If not, see <http://www.gnu.org/licenses/>. */ package org.jflicks.ui.view.fe.screen.systemstatus; import java.awt.Color; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.util.Arrays; import javax.swing.AbstractAction; import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.JLayeredPane; import javax.swing.KeyStroke; import javax.swing.SwingConstants; import org.jflicks.job.JobContainer; import org.jflicks.job.JobEvent; import org.jflicks.job.JobListener; import org.jflicks.job.JobManager; import org.jflicks.job.SystemJob; import org.jflicks.nms.NMS; import org.jflicks.nms.State; import org.jflicks.ui.view.fe.ButtonPanel; import org.jflicks.ui.view.fe.FrontEndView; import org.jflicks.ui.view.fe.MessagePanel; import org.jflicks.ui.view.fe.NMSProperty; import org.jflicks.ui.view.fe.ParameterProperty; import org.jflicks.ui.view.fe.screen.Screen; import org.jflicks.ui.view.fe.screen.ScreenEvent; import org.jflicks.update.Update; import org.jflicks.update.UpdateProperty; import org.jflicks.update.UpdateState; import org.jflicks.util.Busy; import org.jflicks.util.Util; import org.jdesktop.swingx.JXLabel; import org.jdesktop.swingx.JXPanel; import org.jdesktop.swingx.painter.MattePainter; /** * This class supports SystemStatus in a front end UI on a TV. * * @author Doug Barnum * @version 1.0 */ public class SystemStatusScreen extends Screen implements ParameterProperty, NMSProperty, UpdateProperty, ActionListener, JobListener { private static final String REQUEST_GUIDE_UPDATE = "Request Guide Update"; private static final String STATISTICS = "Statistics"; private static final String RSYNC_MESSAGE = "sending incremental file list"; private static final long GIGABYTE = 1073741824L; private static final String CANCEL = "Cancel"; private static final String CERTAIN = "Are you certain?"; private NMS[] nms; private String[] parameters; private String selectedParameter; private JXPanel waitPanel; private MessagePanel messagePanel; private boolean popupEnabled; private ButtonPanel buttonPanel; private UpdateOpenJob updateOpenJob; private UpdateJob updateJob; private Update update; private UpdateState updateState; /** * Simple empty constructor. */ public SystemStatusScreen() { setTitle("System Status"); BufferedImage bi = getImageByName("SystemStatus"); setDefaultBackgroundImage(bi); String[] array = { REQUEST_GUIDE_UPDATE, STATISTICS }; setParameters(array); InputMap map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); UpAction upAction = new UpAction(); map.put(KeyStroke.getKeyStroke("UP"), "up"); getActionMap().put("up", upAction); DownAction downAction = new DownAction(); map.put(KeyStroke.getKeyStroke("DOWN"), "down"); getActionMap().put("down", downAction); } /** * {@inheritDoc} */ public NMS[] getNMS() { NMS[] result = null; if (nms != null) { result = Arrays.copyOf(nms, nms.length); } return (result); } /** * {@inheritDoc} */ public void setNMS(NMS[] array) { if (array != null) { nms = Arrays.copyOf(array, array.length); } else { nms = null; } } /** * {@inheritDoc} */ public String[] getParameters() { String[] result = null; if (parameters != null) { result = Arrays.copyOf(parameters, parameters.length); } return (result); } private void setParameters(String[] array) { if (array != null) { parameters = Arrays.copyOf(array, array.length); } else { parameters = null; } } /** * {@inheritDoc} */ public String getSelectedParameter() { return (selectedParameter); } /** * {@inheritDoc} */ public void setSelectedParameter(String s) { selectedParameter = s; } /** * {@inheritDoc} */ public Update getUpdate() { return (update); } /** * {@inheritDoc} */ public void setUpdate(Update u) { update = u; } private UpdateState getUpdateState() { return (updateState); } private void setUpdateState(UpdateState us) { updateState = us; } /** * {@inheritDoc} */ public void save() { } /** * {@inheritDoc} */ public void commandReceived(String command) { } /** * Override so we can start up the player. * * @param b When true we are ready to start the player. */ public void setVisible(boolean b) { super.setVisible(b); if (b) { if (isParameterRequestGuideUpdate()) { updateLayout(false); popup(CERTAIN); } else if (isParameterStatistics()) { MessagePanel mp = getMessagePanel(); StringBuilder sb = new StringBuilder(); NMS[] narray = getNMS(); if ((mp != null) && (sb != null) && (narray != null) && (narray.length > 0)) { State state = narray[0].getState(); for (int i = 1; i < narray.length; i++) { state = state.merge(narray[i].getState()); } // At this point we have totals on our servers. if (narray.length > 1) { sb.append("You have " + narray.length + " jflicks" + " media system servers on your network."); } else { sb.append("You have 1 jflicks media system server" + " on your network."); } sb.append("\n\n"); long gigs = state.getCapacity() / GIGABYTE; sb.append("Total Recording Space:\t" + gigs + " GB"); sb.append("\n"); gigs = state.getFree() / GIGABYTE; long hours = gigs / 5; sb.append("Free Recording Space:\t" + gigs + " GB"); sb.append("\n\n"); sb.append("About " + hours + " hours of HD video remain."); sb.append("\n\n"); sb.append("Total Current Recordings:\t" + state.getRecordingCount()); sb.append("\n"); sb.append("Number of Recorders:\t" + state.getRecorderCount()); sb.append("\n"); sb.append("Busy Recorders Now:\t" + state.getRecorderBusyCount()); sb.append("\n\n"); String[] cats = state.getVideoCategories(); if ((cats != null) && (cats.length > 0)) { sb.append("Video Category Names:\t"); for (int i = 0; i < cats.length; i++) { if (i > 0) { sb.append(", "); } sb.append(cats[i]); } sb.append("\n"); sb.append("Total in Video Library:\t" + state.getVideoCount()); sb.append("\n"); } mp.setLineWrap(true); mp.setMessage(sb.toString()); updateLayout(false); } } } } /** * {@inheritDoc} */ public void performLayout(Dimension d) { JLayeredPane pane = getLayeredPane(); if ((d != null) && (pane != null)) { FrontEndView fev = (FrontEndView) getView(); int width = (int) d.getWidth(); int height = (int) d.getHeight(); JXPanel panel = new JXPanel(new BorderLayout()); JXLabel l = new JXLabel("Working, please wait..."); l.setHorizontalTextPosition(SwingConstants.CENTER); l.setHorizontalAlignment(SwingConstants.CENTER); l.setFont(getLargeFont()); panel.add(l, BorderLayout.CENTER); MattePainter p = new MattePainter(Color.BLACK); panel.setBackgroundPainter(p); panel.setBounds(0, 0, width, height); setWaitPanel(panel); MessagePanel mp = new MessagePanel(); mp.setBounds(0, 0, width, height); setMessagePanel(mp); setDefaultBackgroundImage( Util.resize(getDefaultBackgroundImage(), width, height)); } } private void updateLayout(boolean wait) { JLayeredPane pane = getLayeredPane(); if (pane != null) { pane.removeAll(); if (wait) { pane.add(getWaitPanel(), Integer.valueOf(100)); } else { if (isParameterRequestGuideUpdate()) { pane.add(getMessagePanel(), Integer.valueOf(100)); } else if (isParameterStatistics()) { pane.add(getMessagePanel(), Integer.valueOf(100)); } } } } /** * {@inheritDoc} */ public void actionPerformed(ActionEvent event) { ButtonPanel bp = getButtonPanel(); if (bp != null) { if (!CANCEL.equals(bp.getSelectedButton())) { if (isParameterRequestGuideUpdate()) { MessagePanel mp = getMessagePanel(); StringBuilder sb = new StringBuilder(); NMS[] narray = getNMS(); if ((mp != null) && (sb != null) && (narray != null) && (narray.length > 0)) { int count = 0; for (int i = 0; i < narray.length; i++) { if (narray[i].requestProgramDataUpdate()) { count++; } } // At this point we have totals on our servers. if (narray.length > 1) { sb.append("You have " + narray.length + " jflicks" + " media system servers on your network."); } else { sb.append("You have 1 jflicks media system server" + " on your network."); } sb.append("\n\n"); sb.append("And " + count + " of them will update" + "guide data."); mp.setLineWrap(true); mp.setMessage(sb.toString()); updateLayout(false); } } } } unpopup(); } /** * {@inheritDoc} */ public void jobUpdate(JobEvent event) { if (event.getType() == JobEvent.COMPLETE) { if (event.getSource() == getUpdateOpenJob()) { if (event.getState() instanceof UpdateState) { UpdateState us = (UpdateState) event.getState(); MessagePanel mp = getMessagePanel(); if (mp != null) { String message = "No need to restart as there were no updates."; int bundleCount = us.getUpdateCount(); if (bundleCount > 0) { if (bundleCount == 1) { message = "There is 1 update."; } else { message = "There are " + bundleCount + " updates."; } mp.setLineWrap(false); mp.setMessage(message); updateLayout(false); setUpdateState(us); popup(message); } else { mp.setLineWrap(false); mp.setMessage(message); updateLayout(false); getUpdate().close(us); } } } } else if (event.getSource() == getUpdateJob()) { if (event.getState() instanceof Boolean) { Boolean bobj = (Boolean) event.getState(); MessagePanel mp = getMessagePanel(); if (mp != null) { String message = "Update complete, please restart."; if (!bobj.booleanValue()) { message = "There was an error, try again later."; } mp.setLineWrap(false); mp.setMessage(message); updateLayout(false); } } } } } private JXPanel getWaitPanel() { return (waitPanel); } private void setWaitPanel(JXPanel p) { waitPanel = p; } private MessagePanel getMessagePanel() { return (messagePanel); } private void setMessagePanel(MessagePanel p) { messagePanel = p; } private ButtonPanel getButtonPanel() { return (buttonPanel); } private void setButtonPanel(ButtonPanel p) { buttonPanel = p; } private UpdateOpenJob getUpdateOpenJob() { return (updateOpenJob); } private void setUpdateOpenJob(UpdateOpenJob j) { updateOpenJob = j; } private UpdateJob getUpdateJob() { return (updateJob); } private void setUpdateJob(UpdateJob j) { updateJob = j; } private boolean isParameterRequestGuideUpdate() { return (REQUEST_GUIDE_UPDATE.equals(getSelectedParameter())); } private boolean isParameterStatistics() { return (STATISTICS.equals(getSelectedParameter())); } private String getScriptExtension() { String result = "sh"; if (Util.isWindows()) { result = "cmd"; } return (result); } private String getScriptPrefix() { String result = ""; if (Util.isLinux()) { result = "./"; } return (result); } private boolean isPopupEnabled() { return (popupEnabled); } private void setPopupEnabled(boolean b) { popupEnabled = b; } private void popup(String select) { JLayeredPane pane = getLayeredPane(); if (pane != null) { setPopupEnabled(true); Dimension d = pane.getSize(); int width = (int) d.getWidth(); int height = (int) d.getHeight(); // See if we have an image as a background... BufferedImage bi = null; FrontEndView fe = (FrontEndView) getView(); if (fe != null) { bi = fe.getLogoImage(); } String[] choices = new String[2]; choices[0] = select; choices[1] = CANCEL; ButtonPanel bp = new ButtonPanel(); bp.addActionListener(this); bp.setButtons(choices); bp.setBufferedImage(bi); setButtonPanel(bp); d = bp.getPreferredSize(); int bpwidth = (int) d.getWidth(); int bpheight = (int) d.getHeight(); int bpx = (int) ((width - bpwidth) / 2); int bpy = (int) ((height - bpheight) / 2); bp.setBounds(bpx, bpy, bpwidth, bpheight); pane.add(bp, Integer.valueOf(300)); bp.setControl(true); bp.setButtons(choices); bp.requestFocus(); } } private void unpopup() { setPopupEnabled(false); JLayeredPane pane = getLayeredPane(); ButtonPanel bp = getButtonPanel(); if ((pane != null) && (bp != null)) { bp.removeActionListener(this); setButtonPanel(null); pane.remove(bp); pane.repaint(); } } class UpAction extends AbstractAction { public UpAction() { } public void actionPerformed(ActionEvent e) { if (isPopupEnabled()) { ButtonPanel bp = getButtonPanel(); if (bp != null) { bp.moveUp(); } } fireScreenEvent(ScreenEvent.USER_INPUT); } } class DownAction extends AbstractAction { public DownAction() { } public void actionPerformed(ActionEvent e) { if (isPopupEnabled()) { ButtonPanel bp = getButtonPanel(); if (bp != null) { bp.moveDown(); } } fireScreenEvent(ScreenEvent.USER_INPUT); } } }