[sword-svn] r145 - in trunk: . app/src/org/crosswire/flashcards app/webstart fonts micro/src/org/crosswire/flashcards src/org/crosswire/flashcards

Apache apache at www.crosswire.org
Sun Dec 30 13:31:15 MST 2007


Author: 
Date: 2007-12-30 13:31:14 -0700 (Sun, 30 Dec 2007)
New Revision: 145

Added:
   trunk/fonts/
   trunk/fonts/GalSILB201.ttf
   trunk/fonts/SILEOT.ttf
Removed:
   trunk/app/src/org/crosswire/flashcards/Debug.java
Modified:
   trunk/app/src/org/crosswire/flashcards/ComplexLesson.java
   trunk/app/src/org/crosswire/flashcards/ComplexLessonSet.java
   trunk/app/src/org/crosswire/flashcards/Editor.java
   trunk/app/src/org/crosswire/flashcards/EditorFrame.java
   trunk/app/src/org/crosswire/flashcards/LessonManager.java
   trunk/app/src/org/crosswire/flashcards/MainMenu.java
   trunk/app/src/org/crosswire/flashcards/Quiz.java
   trunk/app/src/org/crosswire/flashcards/QuizPane.java
   trunk/app/webstart/Flashcards.jnlp
   trunk/build.xml
   trunk/micro/src/org/crosswire/flashcards/MicroLessonSet.java
   trunk/src/org/crosswire/flashcards/FlashCard.java
Log:
Added ability for webstart to work under java 1.6
Embedded lessons in application jar
Removed requirement for special permissions
Added font search logic
Packaged SIL Greek and Hebrew fonts with application
-TAG


Modified: trunk/app/src/org/crosswire/flashcards/ComplexLesson.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/ComplexLesson.java	2007-12-24 02:18:43 UTC (rev 144)
+++ trunk/app/src/org/crosswire/flashcards/ComplexLesson.java	2007-12-30 20:31:14 UTC (rev 145)
@@ -1,286 +1,332 @@
-/*
- * Distribution Licence:
- * FlashCard is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General Public License,
- * version 2 as published by the Free Software Foundation.
- * This program 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.
- * The License is available on the internet at:
- *     http://www.gnu.org/copyleft/gpl.html,
- * or by writing to:
- *     Free Software Foundation, Inc.
- *     59 Temple Place - Suite 330
- *     Boston, MA 02111-1307, USA
- *
- *
- * Copyright: 2004 CrossWire Bible Society
- */
-
-package org.crosswire.flashcards;
-
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontFormatException;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.InputStream;
-import java.net.JarURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.Properties;
-
-import javax.imageio.ImageIO;
-import java.awt.geom.Rectangle2D;
-
-
-/**
- * A Lesson is an ordered list of FlashCards.
- * The lesson also has a description which is useful for showing to a user.
- */
-public class ComplexLesson extends Lesson {
-
-     private static final String DIR_PROJECT = ".flashcards";
-
-     public ComplexLesson(String url) throws Exception {
-          super(url);
-     }
-
-
-     public ComplexLesson(String url, String description) throws Exception {
-          super(url, description);
-     }
-
-
-     /**
-      * Load this lesson from persistent store named by the lesson's <code>filename</code>.
-      */
-     public void load() {
-          try {
-               String homeProjectPath = System.getProperty("user.home") + File.separator + DIR_PROJECT;
-               URL lessonURL = new URL(getURL());
-               Properties lesson = new Properties();
-               lesson.load(lessonURL.openConnection().getInputStream());
-               int wordCount = Integer.parseInt(lesson.getProperty("wordCount"));
-               setDescription(lesson.getProperty("lessonTitle", getURL().substring(getURL().lastIndexOf('/') + 1)));
-               String font = lesson.getProperty("lessonFont");
-               if (font != null && font.length() > 0) {
-                    String fontPath = homeProjectPath + File.separator + font+ ".ttf";
-                    File fontFile = new File(fontPath);
-                    if (fontFile.exists()) {
-                         String url = fontFile.toURL().toString();
-                         setFont(url);
-                    }
-               }
-               int baseOffset = getURL().lastIndexOf("/");
-               if (baseOffset < 0) {
-                    baseOffset = getURL().lastIndexOf( ("\\"));
-               }
-               String lname = getURL().substring(baseOffset + 1);
-               lname = lname.substring(0, lname.indexOf(".flash"));
-               String audioPath = getURL().substring(0, baseOffset) + "/audio";
-
-               for (int i = 0; i < wordCount; i++) {
-                    FlashCard f = new FlashCard(lesson.getProperty("word" + i), lesson.getProperty("answers" + i));
-                    String audioURLString = audioPath + "/" + lname + "_" + Integer.toString(i) + ".wav";
-                    URL audioURL = new URL(audioURLString);
-                    try {
-                         audioURL.openConnection().getInputStream();
-                         f.setAudioURL(audioURLString);
-                    }
-                    catch (Exception e) {}
-                    add(f);
-               }
-               setModified(false);
-          }
-          catch (IOException e1) {
-               /* ignore it */
-          }
-     }
-
-
-     /**
-      * Save this lesson to persistent store named by the lesson's <code>filename</code>.
-      */
-     public void store() {
-          Properties lesson = new Properties();
-          OutputStream outStream = null;
-          try {
-               lesson.setProperty("lessonTitle", getDescription());
-               int i = 0;
-               for (; i < getFlashcards().size(); i++) {
-                    FlashCard flashCard = (FlashCard) getFlashcards().get(i);
-                    lesson.setProperty("word" + i, flashCard.getFront());
-                    lesson.setProperty("answers" + i, flashCard.getBack());
-               }
-               lesson.setProperty("wordCount", Integer.toString(i));
-
-               // Save it as a "home" resource.
-               URL filePath = new URL(getURL());
-               File file = null;
-               URLConnection connection = filePath.openConnection();
-               if (connection instanceof JarURLConnection) {
-                    file = new File(LessonManager.instance().getHomeProjectPath() + File.separator +
-                                    ( (JarURLConnection) connection).getEntryName());
-               }
-               else {
-                    file = new File(filePath.getFile());
-               }
-               File dir = file.getParentFile();
-               // Is it already a directory ?
-               if (!dir.isDirectory()) {
-                    dir.mkdirs();
-               }
-               outStream = new FileOutputStream(file);
-               lesson.store(outStream, "Flash Lesson");
-               setModified(false);
-          }
-          catch (IOException ex) {
-               Debug.error(this.getClass().getName(), ex.getMessage());
-          }
-          finally {
-               if (outStream != null) {
-                    try {
-                         outStream.close();
-                    }
-                    catch (IOException e) {
-                         Debug.error(this.getClass().getName(), e.getMessage());
-                    }
-               }
-          }
-     }
-
-     public Font loadFont(String url) {
-          Font font = null;
-          if (url.length() > 2) {
-               InputStream is = null;
-               try {
-                    URLConnection connection = new URL(url).openConnection();
-                    is = connection.getInputStream();
-                    font = loadFont(is);
-               }
-               catch (IOException ex) {
-                    ex.printStackTrace(System.err);
-               }
-               catch (FontFormatException e) {
-                    e.printStackTrace(System.err);
-               } finally {
-                    if (is != null) {
-                         try {
-                              is.close();
-                         } catch (IOException e) {
-                              e.printStackTrace(System.err);
-                         }
-                    }
-               }
-          }
-          return font;
-     }
-
-
-     public Font loadFont(InputStream is) throws FontFormatException, IOException {
-          Font font = Font.createFont(Font.TRUETYPE_FONT, is);
-          return font;
-     }
-
-     /**
-      * Save this lesson to persistent store named by the lesson's <code>filename</code>.
-      */
-     public void generateImages() {
-          OutputStream outStream = null;
-          try {
-               // Create an image to save
-               int baseOffset = getURL().lastIndexOf("/");
-               if (baseOffset < 0) {
-                    baseOffset = getURL().lastIndexOf( ("\\"));
-               }
-               String lname = getURL().substring(baseOffset + 1);
-               lname = lname.substring(0, lname.indexOf(".flash"));
-               String imagesPath = getURL().substring(0, baseOffset) + "/images";
-               final int width = 800;
-               final int height = 40;
-               Font font = null;
-               if (getFont() != null && getFont().length() > 0) {
-                    Font newFont = loadFont(getFont());
-                    font = newFont.deriveFont(Font.BOLD, (int)(height*.75));
-               }
-//               else font = new Font(g2d.getFont().getName(), Font.BOLD, (int)(height*.75));
-
-               int i = 0;
-               for (; i < getFlashcards().size(); i++) {
-                    FlashCard f = (FlashCard)getFlashcards().elementAt(i);
-                    String imageURLString = imagesPath + "/" + lname + "_" + Integer.toString(i) + ".png";
-                    // Save it as a "home" resource.
-                    URL filePath = new URL(imageURLString);
-                    File file = null;
-                    URLConnection connection = filePath.openConnection();
-                    if (connection instanceof JarURLConnection) {
-                         file = new File(LessonManager.instance().getHomeProjectPath() + File.separator +
-                                         ( (JarURLConnection) connection).getEntryName());
-                    }
-                    else {
-                         file = new File(filePath.getFile());
-                    }
-                    File dir = file.getParentFile();
-                    // Is it already a directory ?
-                    if (!dir.isDirectory()) {
-                         dir.mkdirs();
-                    }
-                    outStream = new FileOutputStream(file);
-
-                    // Create a buffered image in which to draw
-                    BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-
-                    // Create a graphics contents on the buffered image
-                    Graphics2D g2d = bufferedImage.createGraphics();
-
-                    // Draw graphics
-                    g2d.setColor(Color.white);
-                    g2d.fillRect(0, 0, width, height);
-                    g2d.setColor(Color.black);
-
-                   // We need more intelligent font handling here.  Maybe in load(), when we
-                   // grab the font name, we could also look in the lesson for the font file
-                   // itself, otherwise look for it app-wide (whatever that means)
-                    g2d.setFont((font != null) ? font : g2d.getFont().deriveFont(Font.BOLD, (int)(height*.74)));
-//System.out.println("### Using Font: " + g2d.getFont().getName());
-
-                    Rectangle2D rect = g2d.getFont().getStringBounds(f.getFront(), g2d.getFontRenderContext());
-                    g2d.drawString(f.getFront(), 4, (int)(height*.72));
-                    bufferedImage = bufferedImage.getSubimage(0, 0, (int)(rect.getWidth()+8), 40);
-
-                    // Graphics context no longer needed so dispose it
-                    g2d.dispose();
-
-                    // Write generated image to a file
-                    try {
-                         // Save as PNG
-                         ImageIO.write(bufferedImage, "png", outStream);
-
-                    }
-                    catch (IOException e) {
-                    }
-
-               }
-          }
-          catch (IOException ex) {
-               Debug.error(this.getClass().getName(), ex.getMessage());
-          }
-          finally {
-               if (outStream != null) {
-                    try {
-                         outStream.close();
-                    }
-                    catch (IOException e) {
-                         Debug.error(this.getClass().getName(), e.getMessage());
-                    }
-               }
-          }
-     }
-}
+/*
+ * Distribution Licence:
+ * FlashCard is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License,
+ * version 2 as published by the Free Software Foundation.
+ * This program 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.
+ * The License is available on the internet at:
+ *     http://www.gnu.org/copyleft/gpl.html,
+ * or by writing to:
+ *     Free Software Foundation, Inc.
+ *     59 Temple Place - Suite 330
+ *     Boston, MA 02111-1307, USA
+ *
+ *
+ * Copyright: 2004 CrossWire Bible Society
+ */
+
+package org.crosswire.flashcards;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontFormatException;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Properties;
+
+import javax.imageio.ImageIO;
+import java.awt.geom.Rectangle2D;
+
+
+/**
+ * A Lesson is an ordered list of FlashCards.
+ * The lesson also has a description which is useful for showing to a user.
+ */
+public class ComplexLesson extends Lesson {
+     private static final String DIR_PROJECT = ".flashcards";
+     static String homeProjectPath = "";
+     static {
+     try {
+         homeProjectPath = System.getProperty("user.home") + File.separator + DIR_PROJECT;
+     }
+     catch (Exception e) { e.printStackTrace(); }
+     }
+
+
+     public ComplexLesson(String url) throws Exception {
+          super(url);
+     }
+
+
+     public ComplexLesson(String url, String description) throws Exception {
+          super(url, description);
+     }
+
+
+     /**
+      * Load this lesson from persistent store named by the lesson's <code>filename</code>.
+      */
+     public void load() {
+          try {
+               URL lessonURL = new URL(getURL());
+               Properties lesson = new Properties();
+               lesson.load(lessonURL.openConnection().getInputStream());
+               int wordCount = Integer.parseInt(lesson.getProperty("wordCount"));
+               setDescription(lesson.getProperty("lessonTitle", getURL().substring(getURL().lastIndexOf('/') + 1)));
+
+               // try to find font if we've been given a lessonFont
+               String font = lesson.getProperty("lessonFont");
+               // while loop is not really to loop, but instead for break when we find the font
+               while (font != null && font.length() > 0) {
+
+                    // try to find font in ./<FONT>.ttf
+                    try {
+                        String fontPath = "./" + File.separator + font + ".ttf";
+                        File fontFile = new File(fontPath);
+                        if (fontFile.exists()) {
+                             String url = fontFile.toURL().toString();
+                             setFont(url);
+System.out.println("found font in ./");
+                             break;
+                        }
+                    }
+                    catch (Exception e) { e.printStackTrace(); }
+
+                    // try to find font in ~/.flashcards/<FONT>.ttf
+                    try {
+                        String fontPath = homeProjectPath + File.separator + font + ".ttf";
+                        File fontFile = new File(fontPath);
+                        if (fontFile.exists()) {
+                             String url = fontFile.toURL().toString();
+                             setFont(url);
+System.out.println("found font in ~/.flashcards");
+                             break;
+                        }
+                    }
+                    catch (Exception e) { e.printStackTrace(); }
+
+                    // try to find font on our classpath
+                    try {
+                        URL fontURL = ComplexLesson.class.getResource("/" + font + ".ttf");
+                        if (fontURL != null) {
+                            URLConnection connection = null;
+                            connection = fontURL.openConnection();
+                            setFont(fontURL.toString());
+System.out.println("found font on classpath");
+                            break;
+                        }
+                    }
+                    catch (Exception e) { e.printStackTrace(); }
+
+System.out.println("didn't find font");
+                    break;	// didn't find the font, must break out of while
+               }
+
+               int baseOffset = getURL().lastIndexOf("/");
+               if (baseOffset < 0) {
+                    baseOffset = getURL().lastIndexOf( ("\\"));
+               }
+               String lname = getURL().substring(baseOffset + 1);
+               lname = lname.substring(0, lname.indexOf(".flash"));
+               String audioPath = getURL().substring(0, baseOffset) + "/audio";
+
+               for (int i = 0; i < wordCount; i++) {
+                    FlashCard f = new FlashCard(lesson.getProperty("word" + i), lesson.getProperty("answers" + i));
+                    String audioURLString = audioPath + "/" + lname + "_" + Integer.toString(i) + ".wav";
+                    URL audioURL = new URL(audioURLString);
+                    try {
+                         audioURL.openConnection().getInputStream();
+                         f.setAudioURL(audioURLString);
+                    }
+                    catch (Exception e) {}
+                    add(f);
+               }
+               setModified(false);
+          }
+          catch (IOException e1) {
+               /* ignore it */
+          }
+     }
+
+
+     /**
+      * Save this lesson to persistent store named by the lesson's <code>filename</code>.
+      */
+     public void store() {
+          Properties lesson = new Properties();
+          OutputStream outStream = null;
+          try {
+               lesson.setProperty("lessonTitle", getDescription());
+               int i = 0;
+               for (; i < getFlashcards().size(); i++) {
+                    FlashCard flashCard = (FlashCard) getFlashcards().get(i);
+                    lesson.setProperty("word" + i, flashCard.getFront());
+                    lesson.setProperty("answers" + i, flashCard.getBack());
+               }
+               lesson.setProperty("wordCount", Integer.toString(i));
+
+               // Save it as a "home" resource.
+               URL filePath = new URL(getURL());
+               File file = null;
+               URLConnection connection = filePath.openConnection();
+               if (connection instanceof JarURLConnection) {
+                    file = new File(LessonManager.instance().getHomeProjectPath() + File.separator +
+                                    ( (JarURLConnection) connection).getEntryName());
+               }
+               else {
+                    file = new File(filePath.getFile());
+               }
+               File dir = file.getParentFile();
+               // Is it already a directory ?
+               if (!dir.isDirectory()) {
+                    dir.mkdirs();
+               }
+               outStream = new FileOutputStream(file);
+               lesson.store(outStream, "Flash Lesson");
+               setModified(false);
+          }
+          catch (IOException ex) {
+               ex.printStackTrace();
+          }
+          finally {
+               if (outStream != null) {
+                    try {
+                         outStream.close();
+                    }
+                    catch (IOException e) {
+                         e.printStackTrace();
+                    }
+               }
+          }
+     }
+
+     public Font loadFont(String url) {
+          Font font = null;
+          if (url.length() > 2) {
+               InputStream is = null;
+               try {
+                    URLConnection connection = new URL(url).openConnection();
+                    is = connection.getInputStream();
+                    font = loadFont(is);
+               }
+               catch (IOException ex) {
+                    ex.printStackTrace(System.err);
+               }
+               catch (FontFormatException e) {
+                    e.printStackTrace(System.err);
+               } finally {
+                    if (is != null) {
+                         try {
+                              is.close();
+                         } catch (IOException e) {
+                              e.printStackTrace(System.err);
+                         }
+                    }
+               }
+          }
+          return font;
+     }
+
+
+     public Font loadFont(InputStream is) throws FontFormatException, IOException {
+          Font font = Font.createFont(Font.TRUETYPE_FONT, is);
+          return font;
+     }
+
+     /**
+      * Save this lesson to persistent store named by the lesson's <code>filename</code>.
+      */
+     public void generateImages() {
+          OutputStream outStream = null;
+          try {
+               // Create an image to save
+               int baseOffset = getURL().lastIndexOf("/");
+               if (baseOffset < 0) {
+                    baseOffset = getURL().lastIndexOf( ("\\"));
+               }
+               String lname = getURL().substring(baseOffset + 1);
+               lname = lname.substring(0, lname.indexOf(".flash"));
+               String imagesPath = getURL().substring(0, baseOffset) + "/images";
+               final int width = 800;
+               final int height = 40;
+               Font font = null;
+               if (getFont() != null && getFont().length() > 0) {
+                    Font newFont = loadFont(getFont());
+                    font = newFont.deriveFont(Font.BOLD, (int)(height*.75));
+               }
+//               else font = new Font(g2d.getFont().getName(), Font.BOLD, (int)(height*.75));
+
+               int i = 0;
+               for (; i < getFlashcards().size(); i++) {
+                    FlashCard f = (FlashCard)getFlashcards().elementAt(i);
+                    String imageURLString = imagesPath + "/" + lname + "_" + Integer.toString(i) + ".png";
+                    // Save it as a "home" resource.
+                    URL filePath = new URL(imageURLString);
+                    File file = null;
+                    URLConnection connection = filePath.openConnection();
+                    if (connection instanceof JarURLConnection) {
+                         file = new File(LessonManager.instance().getHomeProjectPath() + File.separator +
+                                         ( (JarURLConnection) connection).getEntryName());
+                    }
+                    else {
+                         file = new File(filePath.getFile());
+                    }
+                    File dir = file.getParentFile();
+                    // Is it already a directory ?
+                    if (!dir.isDirectory()) {
+                         dir.mkdirs();
+                    }
+                    outStream = new FileOutputStream(file);
+
+                    // Create a buffered image in which to draw
+                    BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+
+                    // Create a graphics contents on the buffered image
+                    Graphics2D g2d = bufferedImage.createGraphics();
+
+                    // Draw graphics
+                    g2d.setColor(Color.white);
+                    g2d.fillRect(0, 0, width, height);
+                    g2d.setColor(Color.black);
+
+                   // We need more intelligent font handling here.  Maybe in load(), when we
+                   // grab the font name, we could also look in the lesson for the font file
+                   // itself, otherwise look for it app-wide (whatever that means)
+                    g2d.setFont((font != null) ? font : g2d.getFont().deriveFont(Font.BOLD, (int)(height*.74)));
+//System.out.println("### Using Font: " + g2d.getFont().getName());
+
+                    Rectangle2D rect = g2d.getFont().getStringBounds(f.getFront(), g2d.getFontRenderContext());
+                    g2d.drawString(f.getFront(), 4, (int)(height*.72));
+                    bufferedImage = bufferedImage.getSubimage(0, 0, (int)(rect.getWidth()+8), 40);
+
+                    // Graphics context no longer needed so dispose it
+                    g2d.dispose();
+
+                    // Write generated image to a file
+                    try {
+                         // Save as PNG
+                         ImageIO.write(bufferedImage, "png", outStream);
+
+                    }
+                    catch (IOException e) {
+                    }
+
+               }
+          }
+          catch (IOException ex) {
+               ex.printStackTrace();
+          }
+          finally {
+               if (outStream != null) {
+                    try {
+                         outStream.close();
+                    }
+                    catch (IOException e) {
+                         e.printStackTrace();
+                    }
+               }
+          }
+     }
+}

Modified: trunk/app/src/org/crosswire/flashcards/ComplexLessonSet.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/ComplexLessonSet.java	2007-12-24 02:18:43 UTC (rev 144)
+++ trunk/app/src/org/crosswire/flashcards/ComplexLessonSet.java	2007-12-30 20:31:14 UTC (rev 145)
@@ -1,156 +1,156 @@
-/*
- * Distribution Licence:
- * FlashCard is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General Public License,
- * version 2 as published by the Free Software Foundation.
- * This program 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.
- * The License is available on the internet at:
- *     http://www.gnu.org/copyleft/gpl.html,
- * or by writing to:
- *     Free Software Foundation, Inc.
- *     59 Temple Place - Suite 330
- *     Boston, MA 02111-1307, USA
- *
- * Copyright: 2004 CrossWire Bible Society
- */
-package org.crosswire.flashcards;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.net.JarURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
-import java.text.MessageFormat;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.Locale;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-
-/**
- * A <code>LessonSet</code> is an ordered list of <code>Lesson</code>s.
- * The lessons are sorted by filename.
- * The lesson set also has a description which is useful for showing to a user
- * and a directory name where its Lessons are stored. This directory name is expected to be a relative
- * path and will be stored either in a jar or in the user's FlashCard directory.
- *
- * @author Troy A. Griffitts [scribe at crosswire dot org]
- * @author DM Smith [dmsmith555 at yahoo dot com]
- */
-public class ComplexLessonSet extends LessonSet {
-
-     public ComplexLessonSet(String url) {
-          super(url);
-     }
-
-
-     /**
-      * Load this lesson set from persistent store named by the lesson set's <code>dirname</code>.
-      * This is the union of lessons in the Jar and in the user's flashcard home directory.
-      */
-     protected void load() {
-          if (getURL() == null) { // assert we have an URL
-               return;
-          }
-
-          URL lessonsURL = null;
-          URLConnection connection = null;
-          try {
-               lessonsURL = new URL(getURL());
-               connection = lessonsURL.openConnection();
-          }
-          catch (Exception e1) {
-              Debug.error(this.getClass().getName(), e1.getMessage());
-          }
-          if (connection instanceof JarURLConnection) {
-               JarURLConnection jarConnection = (JarURLConnection) connection;
-               loadJarLessonSet(jarConnection);
-          }
-          else if (lessonsURL != null) {
-              loadDirectoryLessonSet(new File(lessonsURL.getFile()));
-          }
-     }
-
-
-     private void loadJarLessonSet(JarURLConnection jarConnection) {
-          String dirName = jarConnection.getEntryName();
-          JarFile jarFile = null;
-          try {
-               jarFile = jarConnection.getJarFile();
-          }
-          catch (Exception e2) {
-              Debug.error(this.getClass().getName(), e2.getMessage());
-          }
-          if (jarFile == null) {
-               return;
-          }
-          Enumeration entries = jarFile.entries();
-          while (entries.hasMoreElements()) {
-               JarEntry jarEntry = (JarEntry) entries.nextElement();
-               String lessonPath = jarEntry.getName();
-               if (lessonPath.startsWith(dirName) && !jarEntry.isDirectory() &&
-                   lessonPath.toUpperCase(Locale.ENGLISH).endsWith(".FLASH")) {
-                    try {
-                         add(new ComplexLesson("jar:" + jarConnection.getJarFileURL() + "!/" + lessonPath));
-                    }
-                    catch (Exception e) {}
-               }
-          }
-     }
-
-
-     /**
-      * Get the relative path names of the lessons in this lesson set from
-      * the user's program home.
-      * @param lessonSet
-      */
-     private void loadDirectoryLessonSet(File directory) {
-               File[] files = directory.listFiles(new FlashFileFilter());
-               if (files == null) {
-                    return;
-               }
-               Arrays.sort(files);
-               for (int i = 0; i < files.length; i++) {
-                    try {
-                         add(new ComplexLesson(files[i].getCanonicalFile().toURL().toString()));
-                    }
-                    catch (Exception e) {}
-               }
-          }
-
-
-     public String getNextLessonFilename() {
-          // This needs work: It should check for collisions
-          String result = null;
-          int next = getLessons().size();
-          Object[] params = {
-                    getURL(), new Integer(next)};
-          MessageFormat format = new MessageFormat("{0}/lesson{1,number,00}.flash");
-          result = format.format(params);
-          return result;
-     }
-
-
-     static class FlashFileFilter implements FilenameFilter {
-         public boolean accept(File dir, String name) {
-              return name.toUpperCase(Locale.ENGLISH).endsWith(".FLASH");
-         }
-    }
-
-
-     /**
-      * Save this lesson to persistent store named by the lesson's <code>dirname</code>.
-      */
-     public void generateImages() {
-          for (int i = 0; i < getLessons().size(); i++) {
-               ComplexLesson lesson = (ComplexLesson) getLessons().elementAt(i);
-		     lesson.generateImages();
-          }
-     }
-
-}
+/*
+ * Distribution Licence:
+ * FlashCard is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License,
+ * version 2 as published by the Free Software Foundation.
+ * This program 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.
+ * The License is available on the internet at:
+ *     http://www.gnu.org/copyleft/gpl.html,
+ * or by writing to:
+ *     Free Software Foundation, Inc.
+ *     59 Temple Place - Suite 330
+ *     Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2004 CrossWire Bible Society
+ */
+package org.crosswire.flashcards;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+
+/**
+ * A <code>LessonSet</code> is an ordered list of <code>Lesson</code>s.
+ * The lessons are sorted by filename.
+ * The lesson set also has a description which is useful for showing to a user
+ * and a directory name where its Lessons are stored. This directory name is expected to be a relative
+ * path and will be stored either in a jar or in the user's FlashCard directory.
+ *
+ * @author Troy A. Griffitts [scribe at crosswire dot org]
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ */
+public class ComplexLessonSet extends LessonSet {
+
+     public ComplexLessonSet(String url) {
+          super(url);
+     }
+
+
+     /**
+      * Load this lesson set from persistent store named by the lesson set's <code>dirname</code>.
+      * This is the union of lessons in the Jar and in the user's flashcard home directory.
+      */
+     protected void load() {
+          if (getURL() == null) { // assert we have an URL
+               return;
+          }
+
+          URL lessonsURL = null;
+          URLConnection connection = null;
+          try {
+               lessonsURL = new URL(getURL());
+               connection = lessonsURL.openConnection();
+          }
+          catch (Exception e1) {
+              e1.printStackTrace();
+          }
+          if (connection instanceof JarURLConnection) {
+               JarURLConnection jarConnection = (JarURLConnection) connection;
+               loadJarLessonSet(jarConnection);
+          }
+          else if (lessonsURL != null) {
+              loadDirectoryLessonSet(new File(lessonsURL.getFile()));
+          }
+     }
+
+
+     private void loadJarLessonSet(JarURLConnection jarConnection) {
+          String dirName = jarConnection.getEntryName();
+          JarFile jarFile = null;
+          try {
+               jarFile = jarConnection.getJarFile();
+          }
+          catch (Exception e2) {
+              e2.printStackTrace();
+          }
+          if (jarFile == null) {
+               return;
+          }
+          Enumeration entries = jarFile.entries();
+          while (entries.hasMoreElements()) {
+               JarEntry jarEntry = (JarEntry) entries.nextElement();
+               String lessonPath = jarEntry.getName();
+               if (lessonPath.startsWith(dirName) && !jarEntry.isDirectory() &&
+                   lessonPath.toUpperCase(Locale.ENGLISH).endsWith(".FLASH")) {
+                    try {
+                         add(new ComplexLesson("jar:" + jarConnection.getJarFileURL() + "!/" + lessonPath));
+                    }
+                    catch (Exception e) {e.printStackTrace();}
+               }
+          }
+     }
+
+
+     /**
+      * Get the relative path names of the lessons in this lesson set from
+      * the user's program home.
+      * @param lessonSet
+      */
+     private void loadDirectoryLessonSet(File directory) {
+               File[] files = directory.listFiles(new FlashFileFilter());
+               if (files == null) {
+                    return;
+               }
+               Arrays.sort(files);
+               for (int i = 0; i < files.length; i++) {
+                    try {
+                         add(new ComplexLesson(files[i].getCanonicalFile().toURL().toString()));
+                    }
+                    catch (Exception e) {}
+               }
+          }
+
+
+     public String getNextLessonFilename() {
+          // This needs work: It should check for collisions
+          String result = null;
+          int next = getLessons().size();
+          Object[] params = {
+                    getURL(), new Integer(next)};
+          MessageFormat format = new MessageFormat("{0}/lesson{1,number,00}.flash");
+          result = format.format(params);
+          return result;
+     }
+
+
+     static class FlashFileFilter implements FilenameFilter {
+         public boolean accept(File dir, String name) {
+              return name.toUpperCase(Locale.ENGLISH).endsWith(".FLASH");
+         }
+    }
+
+
+     /**
+      * Save this lesson to persistent store named by the lesson's <code>dirname</code>.
+      */
+     public void generateImages() {
+          for (int i = 0; i < getLessons().size(); i++) {
+               ComplexLesson lesson = (ComplexLesson) getLessons().elementAt(i);
+		     lesson.generateImages();
+          }
+     }
+
+}

Deleted: trunk/app/src/org/crosswire/flashcards/Debug.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/Debug.java	2007-12-24 02:18:43 UTC (rev 144)
+++ trunk/app/src/org/crosswire/flashcards/Debug.java	2007-12-30 20:31:14 UTC (rev 145)
@@ -1,143 +0,0 @@
-/*
- * Distribution Licence:
- * FlashCard is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General Public License,
- * version 2 as published by the Free Software Foundation.
- * This program 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.
- * The License is available on the internet at:
- *     http://www.gnu.org/copyleft/gpl.html,
- * or by writing to:
- *     Free Software Foundation, Inc.
- *     59 Temple Place - Suite 330
- *     Boston, MA 02111-1307, USA
- * 
- * The copyright to this program is held by it's authors
- * Copyright: 2004
- */
-///////////////////////////////////////////////////////////////////////////
-//
-// Debug.java
-//
-// Help with debugging!
-//
-// Copyright : 2004 CrossWire Bible Society http://crosswire.org
-//
-///////////////////////////////////////////////////////////////////////////
-
-package org.crosswire.flashcards;
-
-import java.io.PrintStream;
-
-class Debug {
-
-    //
-    // Attributes
-    //
-
-    private static boolean enabled = false;
-    private static boolean trace = true;
-    private static boolean inform = true;
-    private static boolean warn = true;
-    private static boolean error = true;
-    private static PrintStream printStream = System.err;
-
-    // Singleton class
-    private Debug() {}
-
-    //
-    // Methods
-    //
-
-    // ---------------
-    static boolean getEnabled( ) { return enabled; }
-
-    // ---------------
-    static void setEnabled( boolean enabled ) { Debug.enabled = enabled; }
-
-    // ---------------
-    static boolean getTrace( ) { return trace; }
-
-    // ---------------
-    static void setTrace( boolean trace ) { Debug.trace = trace; }
-
-    // ---------------
-    static boolean getInform( ) { return inform; }
-
-    // ---------------
-    static void setInform( boolean inform ) { Debug.inform = inform; }
-
-    // ---------------
-    static boolean getWarn( ) { return warn; }
-
-    // ---------------
-    static void setWarn( boolean warn ) { Debug.warn = warn; }
-
-    // ---------------
-    static boolean getError( ) { return error; }
-
-    // ---------------
-    static void setError( boolean error ) { Debug.error = error; }
-
-    // ---------------
-    static PrintStream getPrintStream( ) { return printStream; }
-
-    // ---------------
-    static void setPrintStream( PrintStream printStream ) {
-
-        Debug.printStream = printStream;
-
-    }
-
-    // ---------------
-    static void trace( String identity, String message ) {
-
-        if( null != printStream && trace && enabled ) {
-
-            Debug.printStream.print( " TRACE : " + identity + " : " +
-                                     Thread.currentThread( ) + "\n" + message );
-
-        }
-
-    }
-
-    // ---------------
-    static void inform( String identity, String message ) {
-
-        if( null != printStream && inform && enabled ) {
-
-            Debug.printStream.print( "INFORM : " + identity + " : " +
-                                     Thread.currentThread( ) + "\n" + message );
-
-        }
-
-    }
-
-    // ---------------
-    static void warn( String identity, String message ) {
-
-        if( null != printStream && warn && enabled ) {
-
-            Debug.printStream.print( "  WARN : " + identity + " : " +
-                                     Thread.currentThread( ) + "\n" + message );
-
-        }
-
-    }
-
-    // ---------------
-    static void error( String identity, String message ) {
-
-        if( null != printStream && error ) {
-
-            Debug.printStream.print( " ERROR : " + identity + " : " +
-                                     Thread.currentThread( ) + "\n" + message );
-
-        }
-
-    }
-
-}

Modified: trunk/app/src/org/crosswire/flashcards/Editor.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/Editor.java	2007-12-24 02:18:43 UTC (rev 144)
+++ trunk/app/src/org/crosswire/flashcards/Editor.java	2007-12-30 20:31:14 UTC (rev 145)
@@ -91,10 +91,6 @@
 
         for (int index = 0; arguments.length > index; ++index)
         {
-            if (arguments[index].equals("-debug"))
-            {
-                Debug.setEnabled( true );
-            }
         }
 
         // Set the "Look And Feel"

Modified: trunk/app/src/org/crosswire/flashcards/EditorFrame.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/EditorFrame.java	2007-12-24 02:18:43 UTC (rev 144)
+++ trunk/app/src/org/crosswire/flashcards/EditorFrame.java	2007-12-30 20:31:14 UTC (rev 145)
@@ -269,13 +269,13 @@
             lesson.load(inStream);
 
         } catch(IOException e) {
-            Debug.error(this.getClass().getName(), e.getMessage());
+            e.printStackTrace();
         } finally {
             if (inStream != null) {
                 try {
                     inStream.close();
                 } catch (IOException e) {
-                    Debug.error(this.getClass().getName(), e.getMessage());
+                    e.printStackTrace();
                 }
             }
         }
@@ -307,13 +307,13 @@
             outStream = new FileOutputStream(cwdPath + "/" + lesson.getProperty("fileName"));
             lesson.store(outStream, "Flash Lesson");
         } catch (IOException ex) {
-            Debug.error(this.getClass().getName(), ex.getMessage());
+            ex.printStackTrace();
         } finally {
             if (outStream != null) {
                 try {
                     outStream.close();
                 } catch (IOException e) {
-                    Debug.error(this.getClass().getName(), e.getMessage());
+                    e.printStackTrace();
                 }
             }
         }
@@ -342,7 +342,7 @@
                 wordText.loadFont( new FileInputStream( fontPath.getText( ) ) );
 
             } catch( Exception exception ) {
-                Debug.error(this.getClass().getName(), exception.getMessage());
+                exception.printStackTrace();
             }
 
         }
@@ -395,7 +395,7 @@
                 loadLesson(dialog.getSelectedFile().getCanonicalPath());
                 cwdPath = dialog.getCurrentDirectory().getCanonicalPath();
             } catch( IOException ioe ) {
-                Debug.error(this.getClass().getName(), ioe.getMessage());
+                ioe.printStackTrace();
             }
         }
     }
@@ -417,13 +417,13 @@
                 wordText.loadFont(inStream);
             }
             catch (Exception ex) {
-                Debug.error(this.getClass().getName(), ex.getMessage());
+                ex.printStackTrace();
             } finally {
                 if (inStream != null) {
                     try {
                         inStream.close();
                     } catch (IOException e1) {
-                        Debug.error(this.getClass().getName(), e1.getMessage());
+                        e1.printStackTrace();
                     }
                 }
             }

Modified: trunk/app/src/org/crosswire/flashcards/LessonManager.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/LessonManager.java	2007-12-24 02:18:43 UTC (rev 144)
+++ trunk/app/src/org/crosswire/flashcards/LessonManager.java	2007-12-30 20:31:14 UTC (rev 145)
@@ -1,316 +1,346 @@
-/*
- * Distribution Licence:
- * FlashCard is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General Public License,
- * version 2 as published by the Free Software Foundation.
- * This program 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.
- * The License is available on the internet at:
- *     http://www.gnu.org/copyleft/gpl.html,
- * or by writing to:
- *     Free Software Foundation, Inc.
- *     59 Temple Place - Suite 330
- *     Boston, MA 02111-1307, USA
- *
- * Copyright: 2004 CrossWire Bible Society
- */
-package org.crosswire.flashcards;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.net.JarURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.Locale;
-import java.util.Vector;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-
-/**
- * The <code>LessonManager</code> provides the management of <code>LessonSet</code>s.
- *
- * @author Troy A. Griffitts [scribe at crosswire dot org]
- * @author DM Smith [dmsmith555 at yahoo dot com]
- */
-public class LessonManager {
-
-     public static final String LESSON_ROOT = "lessons";
-     private static final String DIR_PROJECT = ".flashcards";
-     private static LessonManager instance = new LessonManager();
-
-     /**
-      * An ordered list of <code>lessonSets</code>
-      */
-     private Vector lessonSets = new Vector();
-     private File homeLessonDir = null;
-     private String homeProjectPath = null;
-
-     public static LessonManager instance() {
-          return instance;
-     }
-
-
-     private LessonManager() {
-         try {
-         homeProjectPath = System.getProperty("user.home") + File.separator + DIR_PROJECT;
-         homeLessonDir = new File(homeProjectPath + File.separator + LESSON_ROOT);
-         }
-         catch (Exception e) { e.printStackTrace(); }
-         load();
-     }
-
-
-     /**
-      * Appends the specified <code>Lesson</code> to the end of this list.
-      *
-      * @param flashCard to be appended to this list.
-      */
-     public void add(LessonSet lessonSet) {
-          LessonSet exists = getLessonSet(lessonSet.getDescription());
-          if (exists == null) {
-               lessonSets.add(lessonSet);
-          }
-          else {
-               exists.augment(lessonSet);
-          }
-     }
-
-
-     public Vector getLessonSets() {
-          return lessonSets;
-     }
-
-     public LessonSet getLessonSet(String description) {
-          for (int i = 0; i < lessonSets.size(); i++) {
-               LessonSet ls = (LessonSet) lessonSets.elementAt(i);
-               if (description.equals(ls.getDescription())) {
-                    return ls;
-               }
-          }
-          return null;
-     }
-
-
-     /**
-      * Load this lesson from persistent store named by the lesson's <code>LESSON_ROOT</code>.
-      */
-     public void load() {
-          // see if there are any jars in our CWD with lesson sets
-          loadLessonSetsFromJarDir("./");
-
-          // see if there are any lesson sets in our home project dir
-          loadLessonSetsFromDir(homeLessonDir);
-
-          // find the directory containing this
-          // search all jars in that directory for lesson sets
-          String thisName = LessonManager.class.getName();
-          String thisRes = "/" + thisName.replace('.', '/') + ".class";
-          URL thisURL = LessonManager.class.getResource(thisRes);
-          if (thisURL == null) {
-              return;
-          }
-          URLConnection thisCon = null;
-          try {
-              thisCon = thisURL.openConnection();
-          }
-          catch (Exception e1) {
-              e1.printStackTrace();
-          }
-          if (thisCon instanceof JarURLConnection) {
-               JarURLConnection jarConnection = (JarURLConnection) thisCon;
-               loadLessonSetsFromJarDir(new File(jarConnection.getJarFileURL().getFile()).getParent());
-          }
-
-          // see if there are any lessons on our path
-          // dig into the jar for lessonSets
-          URL lessonsURL = LessonManager.class.getResource('/' + LESSON_ROOT);
-          if (lessonsURL == null) {
-              return;
-          }
-          URLConnection connection = null;
-          try {
-              connection = lessonsURL.openConnection();
-          }
-          catch (Exception e1) {
-              e1.printStackTrace();
-          }
-          if (connection instanceof JarURLConnection) {
-               JarURLConnection jarConnection = (JarURLConnection) connection;
-               try {
-
-/*
-                    String uri = jarConnection.getJarFileURL().toString();
-                    //stupid bug with webstart
-                    if ((uri.startsWith("file:")) && (!uri.startsWith("file:/"))) {
-                         uri = "file:/" + uri.substring(5);
-                    }
-//                    int value =  JOptionPane.showConfirmDialog(null, uri,
-//                                     "Text Edit", JOptionPane.OK_OPTION) ;
-
-                    loadJarLessonSets(new File(new java.net.URI(uri)));
-*/
-                    loadJarLessonSets(jarConnection.getJarFile());
-               }
-               catch (Exception e) {
-                   e.printStackTrace();
-               }
-          }
-     }
-
-     /**
-      * Load lesson sets from the jar file
-      */
-     private void loadLessonSetsFromJarDir(String path) {
-          try {
-               File lessonDir = new File(path);
-               if (lessonDir.isDirectory()) {
-                    File[] files = lessonDir.listFiles(new JarFileFilter());
-                    if (files != null) {
-                         for (int i = 0; i < files.length; i++) {
-                              loadJarLessonSets(files[i]);
-                         }
-                    }
-               }
-          }
-          catch (Exception e) { e.printStackTrace(); }
-     }
-
-
-     /**
-      * Load lesson sets from the jar file
-      */
-     private void loadJarLessonSets(File jarFile) {
-
-          // Dig into the jar for lessonSets
-          JarFile jjarFile = null;
-          try {
-               jjarFile = new JarFile(jarFile);
-               loadJarLessonSets(jjarFile);
-          }
-          catch (IOException e2) {
-              e2.printStackTrace();
-          }
-     }
-
-
-     /**
-      * Load lesson sets from the jar file
-      */
-     private void loadJarLessonSets(JarFile jjarFile) {
-
-          try {
-               Enumeration entries = jjarFile.entries();
-               while (entries.hasMoreElements()) {
-                    JarEntry jarEntry = (JarEntry) entries.nextElement();
-                    if (jarEntry.isDirectory()) {
-                         String entryName = jarEntry.getName();
-                         // remove trailing '/'
-                         entryName = entryName.substring(0, entryName.length() - 1);
-                         if (entryName.startsWith(LESSON_ROOT) && !entryName.equals(LESSON_ROOT) && !entryName.endsWith("/audio")) {
-                              // let the description be just the directory name and not the path
-                              add(new ComplexLessonSet("jar:" + new File(jjarFile.getName()).getCanonicalFile().toURL().toString() + "!/" + entryName));
-                         }
-                    }
-               }
-          }
-          catch (IOException e2) {
-              e2.printStackTrace();
-          }
-     }
-
-
-     /**
-      * Load lesson sets from the "home" directory
-      */
-     private void loadLessonSetsFromDir(File directory) {
-          try {
-               File[] files = directory.listFiles();
-               if (files == null) {
-                    return;
-               }
-               Arrays.sort(files);
-               for (int i = 0; i < files.length; i++) {
-                    File file = files[i];
-                    if (file.isDirectory() && !file.getName().equals("audio")) {
-                         add(new ComplexLessonSet(files[i].toURL().toString()));
-                    }
-               }
-          }
-          catch (Exception e) {
-               // that's fine.  We just failed to load local files.
-          }
-     }
-
-
-     /**
-      * See if any LessonSet has changes that need to be saved
-      */
-     public boolean isModified() {
-          for (int i = 0; i < lessonSets.size(); i++) {
-               LessonSet lessonSet = (LessonSet) lessonSets.elementAt(i);
-               if (lessonSet.isModified()) {
-                    return true;
-               }
-          }
-          return false;
-     }
-
-
-     /**
-      * Save all the modified lesson sets to persistent store named by the lesson's <code>LESSON_ROOT</code>.
-      */
-     public void store() {
-          for (int i = 0; i < lessonSets.size(); i++) {
-               LessonSet lessonSet = (LessonSet) lessonSets.elementAt(i);
-               if (lessonSet.isModified()) {
-                    lessonSet.store();
-               }
-          }
-     }
-
-     /**
-      * Generate pre-rendered images for each card (useful on mobile phones)
-      */
-     public void genImages() {
-          for (int i = 0; i < lessonSets.size(); i++) {
-               ComplexLessonSet lessonSet = (ComplexLessonSet) lessonSets.elementAt(i);
-               lessonSet.generateImages();
-          }
-     }
-
-
-     public String getHomeProjectPath() {
-          return homeProjectPath;
-     }
-
-
-     static class JarFileFilter implements FilenameFilter {
-         public boolean accept(File dir, String name) {
-              return name.toUpperCase(Locale.ENGLISH).endsWith(".JAR");
-         }
-     }
-
-
-     public static void main(String argv[]) {
-          // Parse the command line arguments
-          String font = null;
-          int action = 0;
-          for (int i = 0; i < argv.length; i++) {
-               if ("-genImages".equals(argv[i])) {
-                    action = 1;
-               }
-          }
-          switch (action) {
-               case 0: System.out.println("usage: LessonManager [-genImages]"); break;
-               case 1: LessonManager.instance().genImages(); break;
-               default: break;
-          }
-     }
-}
+/*
+ * Distribution Licence:
+ * FlashCard is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License,
+ * version 2 as published by the Free Software Foundation.
+ * This program 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.
+ * The License is available on the internet at:
+ *     http://www.gnu.org/copyleft/gpl.html,
+ * or by writing to:
+ *     Free Software Foundation, Inc.
+ *     59 Temple Place - Suite 330
+ *     Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2004 CrossWire Bible Society
+ */
+package org.crosswire.flashcards;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+
+/**
+ * The <code>LessonManager</code> provides the management of <code>LessonSet</code>s.
+ *
+ * @author Troy A. Griffitts [scribe at crosswire dot org]
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ */
+public class LessonManager {
+
+     public static final String LESSON_ROOT = "lessons";
+     private static final String DIR_PROJECT = ".flashcards";
+     private static LessonManager instance = new LessonManager();
+
+     /**
+      * An ordered list of <code>lessonSets</code>
+      */
+     private Vector lessonSets = new Vector();
+     private File homeLessonDir = null;
+     private String homeProjectPath = null;
+
+     public static LessonManager instance() {
+          return instance;
+     }
+
+
+     private LessonManager() {
+         try {
+           homeProjectPath = System.getProperty("user.home") + File.separator + DIR_PROJECT;
+           homeLessonDir = new File(homeProjectPath + File.separator + LESSON_ROOT);
+         }
+         catch (Exception e) { e.printStackTrace(); }
+         load();
+     }
+
+
+     /**
+      * Appends the specified <code>Lesson</code> to the end of this list.
+      *
+      * @param flashCard to be appended to this list.
+      */
+     public void add(LessonSet lessonSet) {
+          LessonSet exists = getLessonSet(lessonSet.getDescription());
+          if (exists == null) {
+               lessonSets.add(lessonSet);
+          }
+          else {
+               exists.augment(lessonSet);
+          }
+     }
+
+
+     public Vector getLessonSets() {
+          return lessonSets;
+     }
+
+     public LessonSet getLessonSet(String description) {
+          for (int i = 0; i < lessonSets.size(); i++) {
+               LessonSet ls = (LessonSet) lessonSets.elementAt(i);
+               if (description.equals(ls.getDescription())) {
+                    return ls;
+               }
+          }
+          return null;
+     }
+
+
+     /**
+      * Load this lesson from persistent store named by the lesson's <code>LESSON_ROOT</code>.
+      */
+     public void load() {
+          // see if there are any jars in our CWD with lesson sets
+          loadLessonSetsFromJarDir("./");
+
+          // see if there are any lesson sets in our home project dir
+          loadLessonSetsFromDir(homeLessonDir);
+
+          // find the directory containing this
+          // search all jars in that directory for lesson sets
+          String thisName = LessonManager.class.getName();
+          String thisRes = "/" + thisName.replace('.', '/') + ".class";
+          URL thisURL = LessonManager.class.getResource(thisRes);
+          if (thisURL == null) {
+              return;
+          }
+          URLConnection thisCon = null;
+          try {
+              thisCon = thisURL.openConnection();
+          }
+          catch (Exception e1) {
+              e1.printStackTrace();
+          }
+          if (thisCon instanceof JarURLConnection) {
+               JarURLConnection jarConnection = (JarURLConnection) thisCon;
+               loadLessonSetsFromJarDir(new File(jarConnection.getJarFileURL().getFile()).getParent());
+          }
+
+          // see if there are any lessons on our path
+          // dig into the jar for lessonSets
+          URL lessonsURL = LessonManager.class.getResource('/' + LESSON_ROOT);
+          if (lessonsURL == null) {
+              return;
+          }
+          URLConnection connection = null;
+          try {
+              connection = lessonsURL.openConnection();
+          }
+          catch (Exception e1) {
+              e1.printStackTrace();
+          }
+          if (connection instanceof JarURLConnection) {
+               JarURLConnection jarConnection = (JarURLConnection) connection;
+               try {
+
+//                    String uri = jarConnection.getJarFileURL().toString();
+                    String uri = new File(jarConnection.getJarFile().getName()).getCanonicalFile().toURL().toString();
+System.out.println("uri = " + uri);
+                    //stupid bug with webstart
+                    if ((uri.startsWith("file:")) && (!uri.startsWith("file:/"))) {
+                         uri = "file:/" + uri.substring(5);
+                    }
+//                    int value =  JOptionPane.showConfirmDialog(null, uri,
+//                                     "Text Edit", JOptionPane.OK_OPTION) ;
+
+System.out.println("uri = " + uri);
+                    loadJarLessonSets(new File(new java.net.URI(uri)));
+/*
+                    loadJarLessonSets(jarConnection.getJarFile());
+*/
+               }
+               catch (Exception e) {
+                   e.printStackTrace();
+               }
+          }
+     }
+
+     /**
+      * Load lesson sets from the jar file
+      */
+     private void loadLessonSetsFromJarDir(String path) {
+          try {
+               File lessonDir = new File(path);
+               if (lessonDir.isDirectory()) {
+                    File[] files = lessonDir.listFiles(new JarFileFilter());
+                    if (files != null) {
+                         for (int i = 0; i < files.length; i++) {
+                              loadJarLessonSets(files[i]);
+                         }
+                    }
+               }
+          }
+          catch (Exception e) { e.printStackTrace(); }
+     }
+
+
+     /**
+      * Load lesson sets from the jar file
+      */
+/*
+     private void loadJarLessonSets(File jarFile) {
+
+          // Dig into the jar for lessonSets
+          JarFile jjarFile = null;
+          try {
+               jjarFile = new JarFile(jarFile);
+               loadJarLessonSets(jjarFile);
+          }
+          catch (IOException e2) {
+              e2.printStackTrace();
+          }
+     }
+
+*/
+     private void loadJarLessonSets(File jarFile) {
+
+          // Dig into the jar for lessonSets
+          JarFile jjarFile = null;
+          try {
+               jjarFile = new JarFile(jarFile);
+               Enumeration entries = jjarFile.entries();
+               while (entries.hasMoreElements()) {
+                    JarEntry jarEntry = (JarEntry) entries.nextElement();
+                    if (jarEntry.isDirectory()) {
+                         String entryName = jarEntry.getName();
+                         // remove trailing '/'
+                         entryName = entryName.substring(0, entryName.length() - 1);
+                         if (entryName.startsWith(LESSON_ROOT) && !entryName.equals(LESSON_ROOT) && !entryName.endsWith("/audio")) {
+                              // let the description be just the directory name and not the path
+                              add(new ComplexLessonSet("jar:" + jarFile.getCanonicalFile().toURL().toString() + "!/" + entryName));
+                         }
+                    }
+               }
+          }
+          catch (IOException e2) {
+              e2.printStackTrace();
+          }
+     }
+
+     /**
+      * Load lesson sets from the jar file
+      */
+     private void loadJarLessonSets(JarFile jjarFile) {
+
+          try {
+               Enumeration entries = jjarFile.entries();
+               while (entries.hasMoreElements()) {
+                    JarEntry jarEntry = (JarEntry) entries.nextElement();
+                    if (jarEntry.isDirectory()) {
+                         String entryName = jarEntry.getName();
+                         // remove trailing '/'
+                         entryName = entryName.substring(0, entryName.length() - 1);
+                         if (entryName.startsWith(LESSON_ROOT) && !entryName.equals(LESSON_ROOT) && !entryName.endsWith("/audio")) {
+                              // let the description be just the directory name and not the path
+System.out.println("jar:" + new File(jjarFile.getName()).getCanonicalFile().toURL().toString() + "!/" + entryName);
+                              add(new ComplexLessonSet("jar:" + new File(jjarFile.getName()).getCanonicalFile().toURL().toString() + "!/" + entryName));
+                         }
+                    }
+               }
+          }
+          catch (IOException e2) {
+              e2.printStackTrace();
+          }
+     }
+
+
+     /**
+      * Load lesson sets from the "home" directory
+      */
+     private void loadLessonSetsFromDir(File directory) {
+          try {
+               File[] files = directory.listFiles();
+               if (files == null) {
+                    return;
+               }
+               Arrays.sort(files);
+               for (int i = 0; i < files.length; i++) {
+                    File file = files[i];
+                    if (file.isDirectory() && !file.getName().equals("audio")) {
+                         add(new ComplexLessonSet(files[i].toURL().toString()));
+                    }
+               }
+          }
+          catch (Exception e) {
+               // that's fine.  We just failed to load local files.
+          }
+     }
+
+
+     /**
+      * See if any LessonSet has changes that need to be saved
+      */
+     public boolean isModified() {
+          for (int i = 0; i < lessonSets.size(); i++) {
+               LessonSet lessonSet = (LessonSet) lessonSets.elementAt(i);
+               if (lessonSet.isModified()) {
+                    return true;
+               }
+          }
+          return false;
+     }
+
+
+     /**
+      * Save all the modified lesson sets to persistent store named by the lesson's <code>LESSON_ROOT</code>.
+      */
+     public void store() {
+          for (int i = 0; i < lessonSets.size(); i++) {
+               LessonSet lessonSet = (LessonSet) lessonSets.elementAt(i);
+               if (lessonSet.isModified()) {
+                    lessonSet.store();
+               }
+          }
+     }
+
+     /**
+      * Generate pre-rendered images for each card (useful on mobile phones)
+      */
+     public void genImages() {
+          for (int i = 0; i < lessonSets.size(); i++) {
+               ComplexLessonSet lessonSet = (ComplexLessonSet) lessonSets.elementAt(i);
+               lessonSet.generateImages();
+          }
+     }
+
+
+     public String getHomeProjectPath() {
+          return homeProjectPath;
+     }
+
+
+     static class JarFileFilter implements FilenameFilter {
+         public boolean accept(File dir, String name) {
+              return name.toUpperCase(Locale.ENGLISH).endsWith(".JAR");
+         }
+     }
+
+
+     public static void main(String argv[]) {
+          // Parse the command line arguments
+          String font = null;
+          int action = 0;
+          for (int i = 0; i < argv.length; i++) {
+               if ("-genImages".equals(argv[i])) {
+                    action = 1;
+               }
+          }
+          switch (action) {
+               case 0: System.out.println("usage: LessonManager [-genImages]"); break;
+               case 1: LessonManager.instance().genImages(); break;
+               default: break;
+          }
+     }
+}

Modified: trunk/app/src/org/crosswire/flashcards/MainMenu.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/MainMenu.java	2007-12-24 02:18:43 UTC (rev 144)
+++ trunk/app/src/org/crosswire/flashcards/MainMenu.java	2007-12-30 20:31:14 UTC (rev 145)
@@ -70,32 +70,6 @@
 
         // Application Menu -> Editor
 
-         // Application Menu -> Debugging
-
-        if( Debug.getEnabled( ) ) {
-
-            menu2 = new JMenu( "Debugging" );
-            DebugAction debugAction = new DebugAction( );
-            trace = new JRadioButtonMenuItem( "Trace" );
-            if( Debug.getTrace( ) ) { trace.setSelected( true ); }
-            trace.addActionListener( debugAction );
-            menu2.add( trace );
-            inform = new JRadioButtonMenuItem( "Inform" );
-            if( Debug.getInform( ) ) { inform.setSelected( true ); }
-            inform.addActionListener( debugAction );
-            menu2.add( inform );
-            warn = new JRadioButtonMenuItem( "Warn" );
-            if( Debug.getWarn( ) ) { warn.setSelected( true ); }
-            warn.addActionListener( debugAction );
-            menu2.add( warn );
-            error = new JRadioButtonMenuItem( "Error" );
-            if( Debug.getError( ) ) { error.setSelected( true ); }
-            error.addActionListener( debugAction );
-            menu2.add( error );
-            menu1.add( menu2 );
-
-        }
-
         // Application Menu -> Exit
 
         item = new JMenuItem( "Exit" );
@@ -119,53 +93,8 @@
 
     }
 
-    //
-    // Classes
-    //
 
     // ---------------
-    class DebugAction extends AbstractAction {
-
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 3017480579590120226L;
-
-        public void actionPerformed( ActionEvent event ) {
-
-            Debug.trace( this.toString( ), "Beginning\n" );
-            Debug.inform( this.toString( ),
-                          "event.getActionCommand( ) = " + event.getActionCommand( ) + "\n" );
-
-            if( event.getActionCommand( ).equals( "Trace" ) ) {
-
-                if( trace.isSelected( ) ) { Debug.setTrace( true ); }
-                else { Debug.setTrace( false ); }
-
-            } else if( event.getActionCommand( ).equals( "Inform" ) ) {
-
-                if( inform.isSelected( ) ) { Debug.setInform( true ); }
-                else { Debug.setInform( false ); }
-
-            } else if( event.getActionCommand( ).equals( "Warn" ) ) {
-
-                if( warn.isSelected( ) ) { Debug.setWarn( true ); }
-                else { Debug.setWarn( false ); }
-
-            } else if( event.getActionCommand( ).equals( "Error" ) ) {
-
-                if( error.isSelected( ) ) { Debug.setError( true ); }
-                else { Debug.setError( false ); }
-
-            }
-
-            Debug.trace( this.toString( ), "Ending\n" );
-
-        }
-
-    }
-
-    // ---------------
     static class ExitAction extends AbstractAction {
 
         /**
@@ -176,11 +105,7 @@
         public ExitAction( ) { super( ); }
 
         public void actionPerformed( ActionEvent event ) {
-
-            Debug.trace( this.toString( ), "Beginning\n" );
             System.exit( 0 );
-            Debug.trace( this.toString( ), "Ending\n" );
-
         }
 
     }
@@ -197,16 +122,13 @@
 
             String aboutString = "FlashCards\n" +
                                  "A Vocabulary Training Tool by CrossWire\n" +
-                                 "(c) 2004 CrossWire Bible Society\n" +
+                                 "(c) 2004-2007 CrossWire Bible Society\n" +
                                  "http://crosswire.org";
 
-            Debug.trace( this.toString( ), "Beginning\n" );
             JOptionPane.showMessageDialog( frame,
                                            aboutString,
                                            "About FlashCards",
                                            JOptionPane.INFORMATION_MESSAGE );
-            Debug.trace( this.toString( ), "Ending\n" );
-
         }
 
     }

Modified: trunk/app/src/org/crosswire/flashcards/Quiz.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/Quiz.java	2007-12-24 02:18:43 UTC (rev 144)
+++ trunk/app/src/org/crosswire/flashcards/Quiz.java	2007-12-30 20:31:14 UTC (rev 145)
@@ -82,13 +82,6 @@
         // Parse the command line arguments
 
         for( int index = 0; arguments.length > index; ++ index ) {
-
-            if( ( arguments [ index ] ).equals( "-debug" ) ) {
-
-                Debug.setEnabled( true );
-
-            }
-
         }
 
         // Set the "Look And Feel"

Modified: trunk/app/src/org/crosswire/flashcards/QuizPane.java
===================================================================
--- trunk/app/src/org/crosswire/flashcards/QuizPane.java	2007-12-24 02:18:43 UTC (rev 144)
+++ trunk/app/src/org/crosswire/flashcards/QuizPane.java	2007-12-30 20:31:14 UTC (rev 145)
@@ -1,577 +1,593 @@
-/*
- * Distribution Licence:
- * FlashCard is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General Public License,
- * version 2 as published by the Free Software Foundation.
- * This program 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.
- * The License is available on the internet at:
- *     http://www.gnu.org/copyleft/gpl.html,
- * or by writing to:
- *     Free Software Foundation, Inc.
- *     59 Temple Place - Suite 330
- *     Boston, MA 02111-1307, USA
- *
- * The copyright to this program is held by it's authors
- * Copyright: 2004
- */
-package org.crosswire.flashcards;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.ComponentOrientation;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.GridLayout;
-import java.awt.SystemColor;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.io.IOException;
-import java.io.Serializable;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Vector;
-
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.DataLine;
-import javax.sound.sampled.LineUnavailableException;
-import javax.sound.sampled.SourceDataLine;
-import javax.swing.BorderFactory;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.SwingConstants;
-
-
-
-
-/**
- * A panel that quizzes over a selection of lessons.
- *
- * @author Troy A. Griffitts [scribe at crosswire dot org]
- * @author DM Smith [dmsmith555 at yahoo dot com]
- */
-public class QuizPane
-          extends JPanel {
-     private static final int NUM_COLUMNS = 2;
-     // NUM_ANSWERS should be a multiple of NUM_COLUMNS.
-     private static final int NUM_ANSWERS = 10;
-     /**
-      * Serialization ID
-      */
-     private static final long serialVersionUID = 8613458092624929167L;
-
-     SetupPane setupPane;
-     List words = new ArrayList();
-     List notLearned = new ArrayList();
-     WordEntry currentWord = null;
-     int wrong = 0;
-     int totalAsked = 0;
-     int totalWrong = 0;
-     boolean shownAnswer = false;
-     JButton startLessonButton = new JButton();
-     JButton playSoundButton = new JButton();
-     JButton showAnswerButton = new JButton();
-     JLabel wordText = new JLabel();
-     JLabel statusBar = new JLabel();
-     JLabel wCount = new JLabel();
-
-     JPanel choicesPanel = new JPanel();
-     GridLayout choicesPanelGridLayout = new GridLayout();
-     JPanel statusPanel = new JPanel();
-     BorderLayout statusPanelBorderLayout = new BorderLayout();
-     JPanel jPanel1 = new JPanel();
-     JPanel jPanel2 = new JPanel();
-     BorderLayout borderLayout1 = new BorderLayout();
-     BorderLayout borderLayout2 = new BorderLayout();
-     JPanel jPanel3 = new JPanel();
-     BorderLayout borderLayout3 = new BorderLayout();
-     JPanel jPanel4 = new JPanel();
-     JPanel jPanel5 = new JPanel();
-     JPanel jPanel6 = new JPanel();
-     BorderLayout borderLayout4 = new BorderLayout();
-
-     static class WordEntry implements Serializable {
-
-          protected String back;
-          protected FlashCard flashCard;
-          protected int attempts;
-          /**
-           * Serialization ID
-           */
-          private static final long serialVersionUID = -8148656461971656626L;
-
-
-          public WordEntry(FlashCard flashCard) {
-               this.flashCard = flashCard;
-               back = flashCard.getBack();
-          }
-
-
-          public void incrementFailures(int failures) {
-               attempts += failures;
-          }
-
-
-          public int getFailures() {
-               return attempts;
-          }
-
-
-          public String getSide(boolean front) {
-               return (front) ? flashCard.getFront() : back;
-          }
-
-          public String getAudioURL() {
-               return flashCard.getAudioURL();
-          }
-
-          public String toString() {
-               return flashCard.getFront();
-          }
-     }
-
-
-     //Construct the frame
-     public QuizPane(SetupPane setupPane) {
-          this.setupPane = setupPane;
-          jbInit();
-     }
-
-
-     //Component initialization
-     private void jbInit() {
-          startLessonButton.setText("Start");
-          startLessonButton.addActionListener(new QuizPane_startLessonButton_actionAdapter(this));
-
-          playSoundButton.setText("Listen");
-          playSoundButton.addActionListener(new QuizPane_playSoundButton_actionAdapter(this));
-          playSoundButton.setVisible(false);
-
-          showAnswerButton.setFocusPainted(true);
-          showAnswerButton.setMnemonic('A');
-          showAnswerButton.setText("Show Answer");
-          showAnswerButton.addActionListener(new QuizPane_showAnswerButton_actionAdapter(this));
-
-          wordText.setBackground(SystemColor.text);
-          wordText.setFont(new Font("Dialog", 0, 30));
-          wordText.setMinimumSize(new Dimension(0, 50));
-          wordText.setPreferredSize(new Dimension(0, 50));
-          wordText.setHorizontalAlignment(SwingConstants.CENTER);
-          wordText.setHorizontalTextPosition(SwingConstants.CENTER);
-
-          statusBar.setBorder(BorderFactory.createEtchedBorder());
-          statusBar.setText(" ");
-          wCount.setBorder(BorderFactory.createEtchedBorder());
-
-          choicesPanel.setLayout(choicesPanelGridLayout);
-          choicesPanelGridLayout.setColumns(NUM_COLUMNS);
-          choicesPanelGridLayout.setRows(0);
-
-          statusPanel.setLayout(statusPanelBorderLayout);
-          statusBar.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
-          jPanel1.setLayout(borderLayout3);
-          jPanel2.setLayout(borderLayout1);
-          jPanel6.setLayout(borderLayout4);
-          statusPanel.add(statusBar, BorderLayout.CENTER);
-          statusPanel.add(wCount, BorderLayout.EAST);
-          setLayout(borderLayout2);
-
-          jPanel3.add(playSoundButton);
-          jPanel4.add(startLessonButton);
-          jPanel5.add(showAnswerButton);
-          this.add(statusPanel, java.awt.BorderLayout.SOUTH);
-          this.add(jPanel2, java.awt.BorderLayout.CENTER);
-          this.add(jPanel1, java.awt.BorderLayout.NORTH);
-          jPanel1.add(jPanel3, java.awt.BorderLayout.CENTER);
-          jPanel1.add(jPanel4, java.awt.BorderLayout.WEST);
-          jPanel1.add(jPanel5, java.awt.BorderLayout.EAST);
-          jPanel2.add(jPanel6, java.awt.BorderLayout.SOUTH);
-          jPanel2.add(wordText, java.awt.BorderLayout.CENTER);
-          jPanel6.add(choicesPanel, java.awt.BorderLayout.CENTER);
-     }
-
-
-     public void deleteChildren(JComponent c) {
-          while (c.getComponentCount() > 0) {
-               c.remove(c.getComponent(0));
-          }
-     }
-
-
-     public void loadTest() {
-//        boolean loadedFont = false;
-          words = new ArrayList();
-          Iterator lessonIter = setupPane.iterator();
-          while (lessonIter.hasNext()) {
-               Lesson lesson = (Lesson) lessonIter.next();
-               Vector cards = lesson.getFlashcards();
-               for (int i = 0; i < cards.size(); i++) {
-                    words.add(new WordEntry( (FlashCard) cards.get(i)));
-               }
-//            if (!loadedFont)
-//            {
-//                String font = lesson.getFont();
-//                if (font.length() > 1)
-//                {
-//                    try
-//                    {
-//                        loadFont(new FileInputStream(font));
-//                        loadedFont = true;
-//                    }
-//                    catch (FileNotFoundException ex)
-//                    {
-//                    }
-//                }
-//            }
-          }
-          // let's combine duplicate words
-          for (int i = 0; i < words.size() - 1; i++) {
-               WordEntry w = (WordEntry) words.get(i);
-               for (int j = i + 1; j < words.size(); j++) {
-                    WordEntry xx = (WordEntry) words.get(j);
-                    if (w.flashCard.getFront().equals(xx.flashCard.getFront())) {
-                         w.back += " or " + xx.back;
-                         words.remove(j);
-                         j--;
-                    }
-               }
-          }
-     }
-
-
-//    public void loadFont(InputStream is)
-//    {
-//        try
-//        {
-//            statusBar.setText("Loading font...");
-//            statusBar.paintImmediately(statusBar.getVisibleRect());
-//            Font font = Font.createFont(Font.TRUETYPE_FONT, is);
-//            Font newFont = font.deriveFont((float) 18.0);
-//            wordText.setFont(newFont);
-//            is.close();
-//            statusBar.setText("New Font Loaded.");
-//        }
-//        catch (Exception ex)
-//        {
-//            ex.printStackTrace();
-//        }
-//    }
-
-     void startLessonButton_actionPerformed(ActionEvent e) {
-          loadTest();
-          notLearned = (List) ((ArrayList) words).clone();
-          totalAsked = 0;
-          totalWrong = 0;
-          showRandomWord(currentWord);
-     }
-
-
-     void playSoundButton_actionPerformed(ActionEvent e1) {
-
-               // assert we have an audioURL
-               if (currentWord.getAudioURL() == null) {
-                    return;
-               }
-
-               final int	EXTERNAL_BUFFER_SIZE = 128000;
-
-               AudioInputStream	audioInputStream = null;
-               try {
-                    URL audioURL = new URL(currentWord.getAudioURL());
-                    audioInputStream = AudioSystem.getAudioInputStream(audioURL);
-               }
-               catch (Exception e) {
-                    e.printStackTrace();
-                    System.exit(1);
-               }
-
-               AudioFormat	audioFormat = audioInputStream.getFormat();
-
-               SourceDataLine	line = null;
-               DataLine.Info	info = new DataLine.Info(SourceDataLine.class,
-                                                                  audioFormat);
-               try {
-                    line = (SourceDataLine) AudioSystem.getLine(info);
-                    line.open(audioFormat);
-               }
-               catch (LineUnavailableException e) {
-                    e.printStackTrace();
-                    System.exit(1);
-               }
-               catch (Exception e) {
-                    e.printStackTrace();
-                    System.exit(1);
-               }
-
-               line.start();
-
-               int	nBytesRead = 0;
-               byte[]	abData = new byte[EXTERNAL_BUFFER_SIZE];
-               while (nBytesRead != -1) {
-                    try {
-                         nBytesRead = audioInputStream.read(abData, 0, abData.length);
-                    }
-                    catch (IOException e) {
-                         e.printStackTrace();
-                    }
-                    if (nBytesRead >= 0) {
-                         int	nBytesWritten = line.write(abData, 0, nBytesRead);
-                    }
-               }
-
-               line.drain();
-               line.close();
-	}
-
-
-     public void showRandomWord(WordEntry last) {
-          deleteChildren(choicesPanel);
-          int numToLearn = notLearned.size();
-          if (numToLearn == 0) {
-               return;
-          }
-          while (currentWord == last) {
-               int wordNum = (int) (Math.random() * notLearned.size());
-               currentWord = (WordEntry) notLearned.get(wordNum);
-          }
-          showWord(currentWord);
-     }
-
-
-     public void showWord(WordEntry w) {
-          currentWord = w;
-
-          playSoundButton.setVisible(currentWord.getAudioURL() != null);
-
-          wordText.setText(w.getSide(!setupPane.isFlipped()));
-          if (setupPane.isNoMultipleChoice()) {
-               choicesPanel.invalidate();
-               choicesPanel.validate();
-               choicesPanel.repaint();
-          }
-          else {
-              List choices = (List) ((ArrayList) words).clone();
-              choices.remove(w);
-
-              // randomly pick answers
-              boolean flipped = setupPane.isFlipped();
-              List picks = new ArrayList();
-              picks.add(createAnswerEntry(w.getSide(flipped)));
-              int size = words.size();
-              while (picks.size() < Math.min(NUM_ANSWERS, size)) {
-                  int c = (int) (Math.random() * choices.size());
-                  WordEntry wc = (WordEntry) choices.get(c);
-                  String answer = wc.getSide(flipped);
-
-                  // some times two different word have the same answer
-                  if (!picks.contains(answer)) {
-                      picks.add(createAnswerEntry(answer));
-                      choices.remove(wc);
-                  }
-              }
-              // Now randomize these answers. To do this we swap the first one
-              // with another.
-              int c = (int) (Math.random() * picks.size());
-              // If we have selected something other than ourselves.
-              if (c > 0) {
-                  picks.add(0, picks.remove(c));
-                  picks.add(c, picks.remove(1));
-              }
-              Iterator iter = picks.iterator();
-              while (iter.hasNext()) {
-                  choicesPanel.add( (Component) iter.next());
-              }
-              wrong = 0;
-              shownAnswer = false;
-              updateStats();
-              choicesPanel.invalidate();
-              choicesPanel.validate();
-              choicesPanel.repaint();
-          }
-     }
-
-
-     Component createAnswerEntry(String answer) {
-          JCheckBox ck = new JCheckBox(answer, false);
-          ck.setFont(new Font("Dialog", 0, 16));
-          ck.addItemListener(new QuizPane_answer_itemAdapter(this));
-          return ck;
-     }
-
-
-     void updateStats() {
-          int percent = 100;
-          if (totalAsked > 0) {
-               percent = (int) ( ( ( (float) (totalAsked - totalWrong)) / (float) totalAsked) * 100);
-          }
-          wCount.setText(Integer.toString(notLearned.size()) + " | " + Integer.toString(totalAsked - totalWrong) + "/" +
-                         Integer.toString(totalAsked) + " (" + Integer.toString(percent) + "%)");
-     }
-
-
-     void answer_itemStateChanged(ItemEvent e) {
-		JCheckBox ck = null;
-          try {
-		     ck = (JCheckBox) e.getItem();
-          }
-          catch (Exception e1) { e1.printStackTrace(); }
-
-          if (ck == null) return;
-
-          if (ck.isSelected()) {
-               totalAsked++;
-               if (ck.getText().compareTo(currentWord.getSide(setupPane.isFlipped())) != 0) {
-                    statusBar.setText("Please try again. " + ck.getText() + " is not correct.");
-                    wrong++;
-                    totalWrong++;
-                    ck.setSelected(false);
-               }
-               else {
-                    if (notLearned.size() > 1) {
-                         statusBar.setText("Correct.  Try this next word");
-                         if (wrong > 0) {
-                              currentWord.incrementFailures(wrong);
-                         }
-                         else {
-                              currentWord.incrementFailures( -1);
-                         }
-                         if (currentWord.getFailures() < 0) {
-                              notLearned.remove(currentWord);
-                         }
-                         showRandomWord(currentWord);
-                    }
-                    else {
-                         notLearned.remove(currentWord);
-                         deleteChildren(choicesPanel);
-                         wordText.setText("-=+* Great! *+=-");
-                         statusBar.setText("Nice Job!  You've mastered all " + words.size() + " words!");
-                    }
-               }
-               updateStats();
-          }
-     }
-
-
-     public void showAnswer() {
-          for (int i = 0; i < choicesPanel.getComponentCount(); i++) {
-               JCheckBox ck = (JCheckBox) choicesPanel.getComponent(i);
-               if (ck.getText().equals(currentWord.getSide(setupPane.isFlipped()))) {
-                    ck.setFont(new Font(ck.getFont().getName(), Font.BOLD | Font.ITALIC, ck.getFont().getSize()));
-                    break;
-               }
-          }
-          shownAnswer = true;
-     }
-
-
-     void showAnswerButton_actionPerformed(ActionEvent e) {
-          if (setupPane.isNoMultipleChoice()) {
-               ++totalAsked; String dialogString = currentWord.getSide(!setupPane.isFlipped()) + "\n" +
-                         currentWord.getSide(setupPane.isFlipped()) + "\n" + "Did You Get It Right?\n";
-               int choice = JOptionPane.showConfirmDialog(this, dialogString, "Result", JOptionPane.YES_NO_OPTION);
-               if (JOptionPane.YES_OPTION == choice) {
-                    notLearned.remove(currentWord);
-               }
-               else {
-                    ++totalWrong;
-               }
-               updateStats();
-               if (notLearned.size() > 0) {
-                    showRandomWord(currentWord);
-               }
-               else {
-                    wordText.setText("-=+* Great! *+=-");
-                    statusBar.setText("Nice Job!  You've mastered all " + words.size() + " words!");
-               }
-          }
-          else {
-               if (!shownAnswer) {
-                    showAnswer();
-                    return;
-               }
-               int next = notLearned.indexOf(currentWord) + 1;
-               if (next == 0) {
-                    return;
-               }
-               if (next >= notLearned.size()) {
-                    next = 0;
-               }
-               deleteChildren(choicesPanel);
-               showWord( (WordEntry) notLearned.get(next));
-               showAnswer();
-          }
-     }
-
-}
-
-
-class QuizPane_startLessonButton_actionAdapter
-          implements ActionListener {
-     QuizPane adaptee;
-
-     QuizPane_startLessonButton_actionAdapter(QuizPane adaptee) {
-          this.adaptee = adaptee;
-     }
-
-
-     public void actionPerformed(ActionEvent e) {
-          adaptee.startLessonButton_actionPerformed(e);
-     }
-}
-
-class QuizPane_playSoundButton_actionAdapter
-          implements ActionListener {
-     QuizPane adaptee;
-
-     QuizPane_playSoundButton_actionAdapter(QuizPane adaptee) {
-          this.adaptee = adaptee;
-     }
-
-
-     public void actionPerformed(ActionEvent e) {
-          adaptee.playSoundButton_actionPerformed(e);
-     }
-}
-
-
-class QuizPane_answer_itemAdapter
-          implements ItemListener {
-     QuizPane adaptee;
-
-     QuizPane_answer_itemAdapter(QuizPane adaptee) {
-          this.adaptee = adaptee;
-     }
-
-
-     public void itemStateChanged(ItemEvent e) {
-          adaptee.answer_itemStateChanged(e);
-     }
-}
-
-
-class QuizPane_showAnswerButton_actionAdapter
-          implements ActionListener {
-     QuizPane adaptee;
-
-     QuizPane_showAnswerButton_actionAdapter(QuizPane adaptee) {
-          this.adaptee = adaptee;
-     }
-
-
-     public void actionPerformed(ActionEvent e) {
-          adaptee.showAnswerButton_actionPerformed(e);
-     }
-}
+/*
+ * Distribution Licence:
+ * FlashCard is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License,
+ * version 2 as published by the Free Software Foundation.
+ * This program 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.
+ * The License is available on the internet at:
+ *     http://www.gnu.org/copyleft/gpl.html,
+ * or by writing to:
+ *     Free Software Foundation, Inc.
+ *     59 Temple Place - Suite 330
+ *     Boston, MA 02111-1307, USA
+ *
+ * The copyright to this program is held by it's authors
+ * Copyright: 2004
+ */
+package org.crosswire.flashcards;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.ComponentOrientation;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.awt.SystemColor;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+import java.util.Hashtable;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+
+
+
+
+/**
+ * A panel that quizzes over a selection of lessons.
+ *
+ * @author Troy A. Griffitts [scribe at crosswire dot org]
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ */
+public class QuizPane
+          extends JPanel {
+     private static final int NUM_COLUMNS = 2;
+     // NUM_ANSWERS should be a multiple of NUM_COLUMNS.
+     private static final int NUM_ANSWERS = 10;
+     private static Hashtable fontCache = new Hashtable();
+
+     /**
+      * Serialization ID
+      */
+     private static final long serialVersionUID = 8613458092624929167L;
+
+     SetupPane setupPane;
+     List words = new ArrayList();
+     List notLearned = new ArrayList();
+     WordEntry currentWord = null;
+     int wrong = 0;
+     int totalAsked = 0;
+     int totalWrong = 0;
+     boolean shownAnswer = false;
+     JButton startLessonButton = new JButton();
+     JButton playSoundButton = new JButton();
+     JButton showAnswerButton = new JButton();
+     JLabel wordText = new JLabel();
+     JLabel statusBar = new JLabel();
+     JLabel wCount = new JLabel();
+
+     JPanel choicesPanel = new JPanel();
+     GridLayout choicesPanelGridLayout = new GridLayout();
+     JPanel statusPanel = new JPanel();
+     BorderLayout statusPanelBorderLayout = new BorderLayout();
+     JPanel jPanel1 = new JPanel();
+     JPanel jPanel2 = new JPanel();
+     BorderLayout borderLayout1 = new BorderLayout();
+     BorderLayout borderLayout2 = new BorderLayout();
+     JPanel jPanel3 = new JPanel();
+     BorderLayout borderLayout3 = new BorderLayout();
+     JPanel jPanel4 = new JPanel();
+     JPanel jPanel5 = new JPanel();
+     JPanel jPanel6 = new JPanel();
+     BorderLayout borderLayout4 = new BorderLayout();
+
+     static class WordEntry implements Serializable {
+
+          protected String back;
+          protected FlashCard flashCard;
+          protected int attempts;
+          protected String fontURL = null;
+          /**
+           * Serialization ID
+           */
+          private static final long serialVersionUID = -8148656461971656626L;
+
+
+          public WordEntry(FlashCard flashCard) {
+               this.flashCard = flashCard;
+               back = flashCard.getBack();
+          }
+
+
+          public void incrementFailures(int failures) {
+               attempts += failures;
+          }
+
+
+          public int getFailures() {
+               return attempts;
+          }
+
+
+          public String getSide(boolean front) {
+               return (front) ? flashCard.getFront() : back;
+          }
+
+          public String getAudioURL() {
+               return flashCard.getAudioURL();
+          }
+
+          public void setFontURL(String fontURL) {
+               this.fontURL = fontURL;
+          }
+
+          public String getFontURL() {
+               return fontURL;
+          }
+
+          public String toString() {
+               return flashCard.getFront();
+          }
+     }
+
+
+     //Construct the frame
+     public QuizPane(SetupPane setupPane) {
+          this.setupPane = setupPane;
+          jbInit();
+     }
+
+
+     //Component initialization
+     private void jbInit() {
+          startLessonButton.setText("Start");
+          startLessonButton.addActionListener(new QuizPane_startLessonButton_actionAdapter(this));
+
+          playSoundButton.setText("Listen");
+          playSoundButton.addActionListener(new QuizPane_playSoundButton_actionAdapter(this));
+          playSoundButton.setVisible(false);
+
+          showAnswerButton.setFocusPainted(true);
+          showAnswerButton.setMnemonic('A');
+          showAnswerButton.setText("Show Answer");
+          showAnswerButton.addActionListener(new QuizPane_showAnswerButton_actionAdapter(this));
+
+          wordText.setBackground(SystemColor.text);
+          wordText.setFont(new Font("Dialog", 0, 30));
+          wordText.setMinimumSize(new Dimension(0, 50));
+          wordText.setPreferredSize(new Dimension(0, 50));
+          wordText.setHorizontalAlignment(SwingConstants.CENTER);
+          wordText.setHorizontalTextPosition(SwingConstants.CENTER);
+
+          statusBar.setBorder(BorderFactory.createEtchedBorder());
+          statusBar.setText(" ");
+          wCount.setBorder(BorderFactory.createEtchedBorder());
+
+          choicesPanel.setLayout(choicesPanelGridLayout);
+          choicesPanelGridLayout.setColumns(NUM_COLUMNS);
+          choicesPanelGridLayout.setRows(0);
+
+          statusPanel.setLayout(statusPanelBorderLayout);
+          statusBar.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
+          jPanel1.setLayout(borderLayout3);
+          jPanel2.setLayout(borderLayout1);
+          jPanel6.setLayout(borderLayout4);
+          statusPanel.add(statusBar, BorderLayout.CENTER);
+          statusPanel.add(wCount, BorderLayout.EAST);
+          setLayout(borderLayout2);
+
+          jPanel3.add(playSoundButton);
+          jPanel4.add(startLessonButton);
+          jPanel5.add(showAnswerButton);
+          this.add(statusPanel, java.awt.BorderLayout.SOUTH);
+          this.add(jPanel2, java.awt.BorderLayout.CENTER);
+          this.add(jPanel1, java.awt.BorderLayout.NORTH);
+          jPanel1.add(jPanel3, java.awt.BorderLayout.CENTER);
+          jPanel1.add(jPanel4, java.awt.BorderLayout.WEST);
+          jPanel1.add(jPanel5, java.awt.BorderLayout.EAST);
+          jPanel2.add(jPanel6, java.awt.BorderLayout.SOUTH);
+          jPanel2.add(wordText, java.awt.BorderLayout.CENTER);
+          jPanel6.add(choicesPanel, java.awt.BorderLayout.CENTER);
+     }
+
+
+     public void deleteChildren(JComponent c) {
+          while (c.getComponentCount() > 0) {
+               c.remove(c.getComponent(0));
+          }
+     }
+
+
+     public void loadTest() {
+          words = new ArrayList();
+          Iterator lessonIter = setupPane.iterator();
+          while (lessonIter.hasNext()) {
+               Lesson lesson = (Lesson) lessonIter.next();
+               Vector cards = lesson.getFlashcards();
+               for (int i = 0; i < cards.size(); i++) {
+                    WordEntry we = new WordEntry( (FlashCard) cards.get(i));
+                    we.setFontURL(lesson.getFont());
+                    words.add(we);
+               }
+          }
+          // let's combine duplicate words
+          for (int i = 0; i < words.size() - 1; i++) {
+               WordEntry w = (WordEntry) words.get(i);
+               for (int j = i + 1; j < words.size(); j++) {
+                    WordEntry xx = (WordEntry) words.get(j);
+                    if (w.flashCard.getFront().equals(xx.flashCard.getFront())) {
+                         w.back += " or " + xx.back;
+                         words.remove(j);
+                         j--;
+                    }
+               }
+          }
+     }
+
+
+    public Font loadFont(String url) {
+        Font retVal = null;
+        try {
+            // see if our font is already loaded...
+            retVal = (Font)fontCache.get(url);
+            if (retVal == null) {
+                statusBar.setText("Loading font...");
+                statusBar.paintImmediately(statusBar.getVisibleRect());
+                URL fontURL = new URL(url);
+                URLConnection uc = fontURL.openConnection();
+                InputStream is = uc.getInputStream();
+                retVal = Font.createFont(Font.TRUETYPE_FONT, is);
+//                Font newFont = font.deriveFont((float) 18.0);
+//                wordText.setFont(newFont);
+                is.close();
+                fontCache.put(url, retVal);
+                statusBar.setText("New Font Loaded.");
+            }
+        }
+        catch (Exception ex) {
+            ex.printStackTrace();
+        }
+        return retVal;
+    }
+
+     void startLessonButton_actionPerformed(ActionEvent e) {
+          loadTest();
+          notLearned = (List) ((ArrayList) words).clone();
+          totalAsked = 0;
+          totalWrong = 0;
+          showRandomWord(currentWord);
+     }
+
+
+     void playSoundButton_actionPerformed(ActionEvent e1) {
+
+               // assert we have an audioURL
+               if (currentWord.getAudioURL() == null) {
+                    return;
+               }
+
+               final int	EXTERNAL_BUFFER_SIZE = 128000;
+
+               AudioInputStream	audioInputStream = null;
+               try {
+                    URL audioURL = new URL(currentWord.getAudioURL());
+                    audioInputStream = AudioSystem.getAudioInputStream(audioURL);
+               }
+               catch (Exception e) {
+                    e.printStackTrace();
+                    System.exit(1);
+               }
+
+               AudioFormat	audioFormat = audioInputStream.getFormat();
+
+               SourceDataLine	line = null;
+               DataLine.Info	info = new DataLine.Info(SourceDataLine.class,
+                                                                  audioFormat);
+               try {
+                    line = (SourceDataLine) AudioSystem.getLine(info);
+                    line.open(audioFormat);
+               }
+               catch (LineUnavailableException e) {
+                    e.printStackTrace();
+                    System.exit(1);
+               }
+               catch (Exception e) {
+                    e.printStackTrace();
+                    System.exit(1);
+               }
+
+               line.start();
+
+               int	nBytesRead = 0;
+               byte[]	abData = new byte[EXTERNAL_BUFFER_SIZE];
+               while (nBytesRead != -1) {
+                    try {
+                         nBytesRead = audioInputStream.read(abData, 0, abData.length);
+                    }
+                    catch (IOException e) {
+                         e.printStackTrace();
+                    }
+                    if (nBytesRead >= 0) {
+                         int	nBytesWritten = line.write(abData, 0, nBytesRead);
+                    }
+               }
+
+               line.drain();
+               line.close();
+	}
+
+
+     public void showRandomWord(WordEntry last) {
+          deleteChildren(choicesPanel);
+          int numToLearn = notLearned.size();
+          if (numToLearn == 0) {
+               return;
+          }
+          while (currentWord == last) {
+               int wordNum = (int) (Math.random() * notLearned.size());
+               currentWord = (WordEntry) notLearned.get(wordNum);
+          }
+          showWord(currentWord);
+     }
+
+
+     public void showWord(WordEntry w) {
+          currentWord = w;
+
+          playSoundButton.setVisible(currentWord.getAudioURL() != null);
+
+          if (currentWord.getFontURL() != null) {
+               Font newFont = loadFont(currentWord.getFontURL());
+               if (newFont != null) {
+                    newFont = newFont.deriveFont((float) 30.0);
+                    wordText.setFont(newFont);
+               }
+          }
+
+
+          wordText.setText(w.getSide(!setupPane.isFlipped()));
+          if (setupPane.isNoMultipleChoice()) {
+               choicesPanel.invalidate();
+               choicesPanel.validate();
+               choicesPanel.repaint();
+          }
+          else {
+              List choices = (List) ((ArrayList) words).clone();
+              choices.remove(w);
+
+              // randomly pick answers
+              boolean flipped = setupPane.isFlipped();
+              List picks = new ArrayList();
+              picks.add(createAnswerEntry(w.getSide(flipped)));
+              int size = words.size();
+              while (picks.size() < Math.min(NUM_ANSWERS, size)) {
+                  int c = (int) (Math.random() * choices.size());
+                  WordEntry wc = (WordEntry) choices.get(c);
+                  String answer = wc.getSide(flipped);
+
+                  // some times two different word have the same answer
+                  if (!picks.contains(answer)) {
+                      picks.add(createAnswerEntry(answer));
+                      choices.remove(wc);
+                  }
+              }
+              // Now randomize these answers. To do this we swap the first one
+              // with another.
+              int c = (int) (Math.random() * picks.size());
+              // If we have selected something other than ourselves.
+              if (c > 0) {
+                  picks.add(0, picks.remove(c));
+                  picks.add(c, picks.remove(1));
+              }
+              Iterator iter = picks.iterator();
+              while (iter.hasNext()) {
+                  choicesPanel.add( (Component) iter.next());
+              }
+              wrong = 0;
+              shownAnswer = false;
+              updateStats();
+              choicesPanel.invalidate();
+              choicesPanel.validate();
+              choicesPanel.repaint();
+          }
+     }
+
+
+     Component createAnswerEntry(String answer) {
+          JCheckBox ck = new JCheckBox(answer, false);
+          ck.setFont(new Font("Dialog", 0, 16));
+          ck.addItemListener(new QuizPane_answer_itemAdapter(this));
+          return ck;
+     }
+
+
+     void updateStats() {
+          int percent = 100;
+          if (totalAsked > 0) {
+               percent = (int) ( ( ( (float) (totalAsked - totalWrong)) / (float) totalAsked) * 100);
+          }
+          wCount.setText(Integer.toString(notLearned.size()) + " | " + Integer.toString(totalAsked - totalWrong) + "/" +
+                         Integer.toString(totalAsked) + " (" + Integer.toString(percent) + "%)");
+     }
+
+
+     void answer_itemStateChanged(ItemEvent e) {
+		JCheckBox ck = null;
+          try {
+		     ck = (JCheckBox) e.getItem();
+          }
+          catch (Exception e1) { e1.printStackTrace(); }
+
+          if (ck == null) return;
+
+          if (ck.isSelected()) {
+               totalAsked++;
+               if (ck.getText().compareTo(currentWord.getSide(setupPane.isFlipped())) != 0) {
+                    statusBar.setText("Please try again. " + ck.getText() + " is not correct.");
+                    wrong++;
+                    totalWrong++;
+                    ck.setSelected(false);
+               }
+               else {
+                    if (notLearned.size() > 1) {
+                         statusBar.setText("Correct.  Try this next word");
+                         if (wrong > 0) {
+                              currentWord.incrementFailures(wrong);
+                         }
+                         else {
+                              currentWord.incrementFailures( -1);
+                         }
+                         if (currentWord.getFailures() < 0) {
+                              notLearned.remove(currentWord);
+                         }
+                         showRandomWord(currentWord);
+                    }
+                    else {
+                         notLearned.remove(currentWord);
+                         deleteChildren(choicesPanel);
+                         wordText.setText("-=+* Great! *+=-");
+                         statusBar.setText("Nice Job!  You've mastered all " + words.size() + " words!");
+                    }
+               }
+               updateStats();
+          }
+     }
+
+
+     public void showAnswer() {
+          for (int i = 0; i < choicesPanel.getComponentCount(); i++) {
+               JCheckBox ck = (JCheckBox) choicesPanel.getComponent(i);
+               if (ck.getText().equals(currentWord.getSide(setupPane.isFlipped()))) {
+                    ck.setFont(new Font(ck.getFont().getName(), Font.BOLD | Font.ITALIC, ck.getFont().getSize()));
+                    break;
+               }
+          }
+          shownAnswer = true;
+     }
+
+
+     void showAnswerButton_actionPerformed(ActionEvent e) {
+          if (setupPane.isNoMultipleChoice()) {
+               ++totalAsked; String dialogString = currentWord.getSide(!setupPane.isFlipped()) + "\n" +
+                         currentWord.getSide(setupPane.isFlipped()) + "\n" + "Did You Get It Right?\n";
+               int choice = JOptionPane.showConfirmDialog(this, dialogString, "Result", JOptionPane.YES_NO_OPTION);
+               if (JOptionPane.YES_OPTION == choice) {
+                    notLearned.remove(currentWord);
+               }
+               else {
+                    ++totalWrong;
+               }
+               updateStats();
+               if (notLearned.size() > 0) {
+                    showRandomWord(currentWord);
+               }
+               else {
+                    wordText.setText("-=+* Great! *+=-");
+                    statusBar.setText("Nice Job!  You've mastered all " + words.size() + " words!");
+               }
+          }
+          else {
+               if (!shownAnswer) {
+                    showAnswer();
+                    return;
+               }
+               int next = notLearned.indexOf(currentWord) + 1;
+               if (next == 0) {
+                    return;
+               }
+               if (next >= notLearned.size()) {
+                    next = 0;
+               }
+               deleteChildren(choicesPanel);
+               showWord( (WordEntry) notLearned.get(next));
+               showAnswer();
+          }
+     }
+
+}
+
+
+class QuizPane_startLessonButton_actionAdapter
+          implements ActionListener {
+     QuizPane adaptee;
+
+     QuizPane_startLessonButton_actionAdapter(QuizPane adaptee) {
+          this.adaptee = adaptee;
+     }
+
+
+     public void actionPerformed(ActionEvent e) {
+          adaptee.startLessonButton_actionPerformed(e);
+     }
+}
+
+class QuizPane_playSoundButton_actionAdapter
+          implements ActionListener {
+     QuizPane adaptee;
+
+     QuizPane_playSoundButton_actionAdapter(QuizPane adaptee) {
+          this.adaptee = adaptee;
+     }
+
+
+     public void actionPerformed(ActionEvent e) {
+          adaptee.playSoundButton_actionPerformed(e);
+     }
+}
+
+
+class QuizPane_answer_itemAdapter
+          implements ItemListener {
+     QuizPane adaptee;
+
+     QuizPane_answer_itemAdapter(QuizPane adaptee) {
+          this.adaptee = adaptee;
+     }
+
+
+     public void itemStateChanged(ItemEvent e) {
+          adaptee.answer_itemStateChanged(e);
+     }
+}
+
+
+class QuizPane_showAnswerButton_actionAdapter
+          implements ActionListener {
+     QuizPane adaptee;
+
+     QuizPane_showAnswerButton_actionAdapter(QuizPane adaptee) {
+          this.adaptee = adaptee;
+     }
+
+
+     public void actionPerformed(ActionEvent e) {
+          adaptee.showAnswerButton_actionPerformed(e);
+     }
+}

Modified: trunk/app/webstart/Flashcards.jnlp
===================================================================
--- trunk/app/webstart/Flashcards.jnlp	2007-12-24 02:18:43 UTC (rev 144)
+++ trunk/app/webstart/Flashcards.jnlp	2007-12-30 20:31:14 UTC (rev 145)
@@ -1,40 +1,40 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE jnlp PUBLIC "-//Sun Microsystems, Inc//DTD JNLP Descriptor 1.0//EN" "jnlp.dtd">
-
-<jnlp spec="1.0+" codebase="http://www.crosswire.org/flashcards/webstart" href="Flashcards.jnlp">
-
-  <information>
-    <title>Flashcards</title>
-    <vendor>Crosswire Bible Society</vendor>
-    <homepage href="http://www.crosswire.org/flashcards"/>
-    <description>Flashcards - A tool for memorizing vocabulary</description>
-    <description kind="short">Flashcards - A tool for learning vocabulary</description>
-    <description kind="tooltip">Flashcards Memorization Tool</description>
-<!-- Put icons here
-    <icon href="icon32.png"/>
-    <icon kind="splash" href="icon64.png"/>
--->
-    <offline-allowed/>
-  </information>
-
-  <security>
-    <!--
-    We need disk io to read lessons from disk,
-    and the ability to read system vars.
-    I'm not sure there is much point in asking for less that everything
-    <all-permissions/>
-    -->
-  </security>
-
-  <resources>
-    <j2se version="1.4+"/>
-    <jar href="flashcards.jar"/>
-<!--    <jar href="lessons.jar"/> -->
-    <!-- if on the Apple Mac, make it play well -->
-    <property name="apple.laf.useScreenMenuBar" value="true"/>
-    <property name="com.apple.mrj.application.apple.menu.about.name" value="Flashcards"/>
-  </resources>
-
-  <application-desc main-class="org.crosswire.flashcards.Quiz"/>
-
-</jnlp>
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE jnlp PUBLIC "-//Sun Microsystems, Inc//DTD JNLP Descriptor 1.0//EN" "jnlp.dtd">
+
+<jnlp spec="1.0+" codebase="http://www.crosswire.org/flashcards/webstart" href="Flashcards.jnlp">
+
+  <information>
+    <title>Flashcards</title>
+    <vendor>Crosswire Bible Society</vendor>
+    <homepage href="http://www.crosswire.org/flashcards"/>
+    <description>Flashcards - A tool for memorizing vocabulary</description>
+    <description kind="short">Flashcards - A tool for learning vocabulary</description>
+    <description kind="tooltip">Flashcards Memorization Tool</description>
+<!-- Put icons here
+    <icon href="icon32.png"/>
+    <icon kind="splash" href="icon64.png"/>
+-->
+    <offline-allowed/>
+  </information>
+
+  <security>
+    <!--
+    We need disk io to read lessons from disk,
+    and the ability to read system vars.
+    I'm not sure there is much point in asking for less that everything
+    <all-permissions/>
+    -->
+  </security>
+
+  <resources>
+    <j2se version="1.4+"/>
+    <jar href="flashcards.jar"/>
+<!--    <jar href="lessons.jar"/> -->
+    <!-- if on the Apple Mac, make it play well -->
+    <property name="apple.laf.useScreenMenuBar" value="true"/>
+    <property name="com.apple.mrj.application.apple.menu.about.name" value="Flashcards"/>
+  </resources>
+
+  <application-desc main-class="org.crosswire.flashcards.Quiz"/>
+
+</jnlp>

Modified: trunk/build.xml
===================================================================
--- trunk/build.xml	2007-12-24 02:18:43 UTC (rev 144)
+++ trunk/build.xml	2007-12-30 20:31:14 UTC (rev 145)
@@ -1,184 +1,187 @@
-<project name="flashcards" default="all">
-
-  <!--=======================================================================
-    == To make eclipse recognise this file as an ant file, go to preferences,
-    == ant and add core.xml to the "Names" field, and then under Workbench,
-    == "File Associations" add a type "core.xml" with ant as the editor.
-    =========================================================================-->
-
-  <!--=======================================================================
-    == These are the standard locations that this build file uses.
-    == This assumes that the build file is in the root of the project.
-    =========================================================================-->
-  <property name="source.root"    value="."/>
-  <property name="source.java"    value="${source.root}/app/src"/>
-  <property name="source.java.common"    value="${source.root}/src"/>
-  <property name="source.res"     value="${source.root}"/>
-  <property name="target.root"    value="${source.root}/target"/>
-  <property name="target.classes" value="${target.root}/classes"/>
-  <property name="target.install" value="${target.root}/install"/>
-  <property name="keystore.file"  value="flshcrds.keystore"/>
-  <property name="keystore.alias" value="flshcrds"/>
-  <property name="keystore.pswd"  value="p455w0rd"/>
-
-  <!--=======================================================================
-    == This is a path to all source directories and files.
-    =========================================================================-->
-  <path id="source.path">
-    <dirset dir="${source.java}" includes="*"/>
-    <dirset dir="${source.java.common}" includes="*"/>
-  </path>
-
-  <!--=======================================================================
-    == These are the non-java resource files
-    == that may appear along side of java files.
-    =========================================================================-->
-  <patternset id="java.non.compile">
-    <include name="**/*"/>
-    <exclude name="**/*.html"/>
-    <exclude name="**/*.java"/>
-    <exclude name="**/*.class"/>
-  </patternset>
-
-  <!--=======================================================================
-    == Mark this build with the current timestamp
-    =========================================================================-->
-  <target name="init" description="Prepare for other tasks">
-    <echo message="Initializing ${ant.project.name}"/>
-    <tstamp/>
-  </target>
-
-  <!--=======================================================================
-    == Clean the intermediate files and build everything
-    =========================================================================-->
-  <target name="all"
-          depends="clean, build"
-          description="Run a full clean/build cycle">
-  </target>
-
-  <!--=======================================================================
-    == Clean the intermediate files.
-    == Also invoke a clean on any dependencies, if any.
-    =========================================================================-->
-  <target name="clean"
-          depends="init"
-          description="Remove the target directory">
-    <delete dir="${target.root}"/>
-  </target>
-
-  <!--=======================================================================
-    == Build all the java files into class files and
-    == create a jar file for the project with the name project.jar,
-    == where project is replaced with the name of the project.
-    == This jar is built to the target.install directory.
-    =========================================================================-->
-  <target name="build" depends="compile, resource, jar.check, keygen" unless="jar.uptodate" description="Run a full build">
-    <mkdir dir="${target.install}"/>
-    <jar jarfile="${target.install}/${ant.project.name}.jar" manifest="${target.classes}/org/crosswire/flashcards/flashcards.manifest">
-      <fileset dir="${target.classes}"/>
-    </jar>
-    <jar jarfile="${target.install}/${ant.project.name}_ws.jar" manifest="${target.classes}/org/crosswire/flashcards/flashcards.manifest">
-      <fileset dir="${target.classes}"/>
-      <fileset dir="${source.root}" includes="lessons/**/*"/>
-    </jar>
-    <copy todir="${target.install}">
-      <fileset dir="${source.root}/app/webstart">
-        <include name="Flashcards.jnlp"/>
-        <include name="*.gif"/>
-      </fileset>
-    </copy>
-
-    <signjar
-          storepass="${keystore.pswd}"
-          alias="${keystore.alias}"
-          keystore="${keystore.file}"
-          keypass="${keystore.pswd}"
-          jar="${target.install}/${ant.project.name}.jar"/>
-    <signjar
-          storepass="${keystore.pswd}"
-          alias="${keystore.alias}"
-          keystore="${keystore.file}"
-          keypass="${keystore.pswd}"
-          jar="${target.install}/${ant.project.name}_ws.jar"/>
-  </target>
-  <target name="jar.check">
-    <uptodate property="jar.uptodate"
-        targetfile="${target.install}/${ant.project.name}.jar">
-      <srcfiles dir="${target.classes}"/>
-    </uptodate>
-  </target>
-
-  <target name="resource" depends="resource.check, keygen" unless="resource.uptodate" description="Run a full build">
-    <mkdir dir="${target.install}"/>
-    <jar jarfile="${target.install}/lessons.jar">
-      <fileset dir="${source.root}" includes="lessons/**/*"/>
-    </jar>
-    <signjar
-          storepass="${keystore.pswd}"
-          alias="${keystore.alias}"
-          keystore="${keystore.file}"
-          keypass="${keystore.pswd}"
-          jar="${target.install}/lessons.jar"/>
-  </target>
-  <target name="resource.check">
-    <uptodate property="resource.uptodate"
-        targetfile="${target.install}/lessons.jar">
-      <srcfiles dir="${source.res}/lessons"/>
-    </uptodate>
-  </target>
-
-  <!--=======================================================================
-    == Compile all the java files under source.path into class files.
-    == Make sure that all the resources in those directories make it over too.
-    =========================================================================-->
-  <target name="compile" description="Compile the source">
-    <mkdir dir="${target.classes}"/>
-    <javac debug="on"
-           srcdir="${source.java.common}"
-           includes="**/*.java"
-           destdir="${target.classes}"
-           source="1.4">
-      <exclude name="**/migrate/*"/>
-    </javac>
-    <javac debug="on"
-           srcdir="${source.java}"
-           includes="**/*.java"
-           destdir="${target.classes}"
-           source="1.4">
-      <exclude name="**/migrate/*"/>
-    </javac>
-    <!-- Copy the resources to the proper org/crosswire directory.
-      == The path separator could be either / or \
-      -->
-    <copy todir="${target.classes}" includeEmptyDirs="false" >
-<!--      <mapper type="regexp" from=".*[\\/](org[\\/].*)" to="\1"/>
--->      <fileset dir="${source.java}">
-        <patternset refid="java.non.compile"/>
-        <exclude name="**/*Test*"/>
-      </fileset>
-    </copy>
-  </target>
-
-  <!--=======================================================================
-    == A keystore is needed to sign jars.
-    == It does not need to be build very often and can be shared.
-    =========================================================================-->
-  <target name="keygen"
-          depends="keygen.check"
-          unless="keygen.uptodate"
-          description="Generates a key for use in signing the JARs">
-    <echo message="Generating keystore for signing jars"/>
-    <genkey alias="${keystore.alias}"
-          storepass="${keystore.pswd}"
-          keystore="${keystore.file}">
-      <dname>
-        <param name="CN" value="The CrossWire Bible Society"/>
-        <param name="OU" value="FlashCards"/>
-        <param name="O" value="Crosswire.org"/>
-      </dname>
-    </genkey>
-  </target>
-  <target name="keygen.check" description="Check the keystore is there">
-    <available property="keygen.uptodate" file="${keystore.file}"/>
-  </target>
-</project>
+<project name="flashcards" default="all">
+
+  <!--=======================================================================
+    == To make eclipse recognise this file as an ant file, go to preferences,
+    == ant and add core.xml to the "Names" field, and then under Workbench,
+    == "File Associations" add a type "core.xml" with ant as the editor.
+    =========================================================================-->
+
+  <!--=======================================================================
+    == These are the standard locations that this build file uses.
+    == This assumes that the build file is in the root of the project.
+    =========================================================================-->
+  <property name="source.root"    value="."/>
+  <property name="source.java"    value="${source.root}/app/src"/>
+  <property name="source.java.common"    value="${source.root}/src"/>
+  <property name="source.res"     value="${source.root}"/>
+  <property name="target.root"    value="${source.root}/target"/>
+  <property name="target.classes" value="${target.root}/classes"/>
+  <property name="target.install" value="${target.root}/install"/>
+  <property name="font.dir"       value="${source.root}/fonts"/>
+  <property name="keystore.file"  value="flshcrds.keystore"/>
+  <property name="keystore.alias" value="flshcrds"/>
+  <property name="keystore.pswd"  value="p455w0rd"/>
+
+  <!--=======================================================================
+    == This is a path to all source directories and files.
+    =========================================================================-->
+  <path id="source.path">
+    <dirset dir="${source.java}" includes="*"/>
+    <dirset dir="${source.java.common}" includes="*"/>
+  </path>
+
+  <!--=======================================================================
+    == These are the non-java resource files
+    == that may appear along side of java files.
+    =========================================================================-->
+  <patternset id="java.non.compile">
+    <include name="**/*"/>
+    <exclude name="**/*.html"/>
+    <exclude name="**/*.java"/>
+    <exclude name="**/*.class"/>
+  </patternset>
+
+  <!--=======================================================================
+    == Mark this build with the current timestamp
+    =========================================================================-->
+  <target name="init" description="Prepare for other tasks">
+    <echo message="Initializing ${ant.project.name}"/>
+    <tstamp/>
+  </target>
+
+  <!--=======================================================================
+    == Clean the intermediate files and build everything
+    =========================================================================-->
+  <target name="all"
+          depends="clean, build"
+          description="Run a full clean/build cycle">
+  </target>
+
+  <!--=======================================================================
+    == Clean the intermediate files.
+    == Also invoke a clean on any dependencies, if any.
+    =========================================================================-->
+  <target name="clean"
+          depends="init"
+          description="Remove the target directory">
+    <delete dir="${target.root}"/>
+  </target>
+
+  <!--=======================================================================
+    == Build all the java files into class files and
+    == create a jar file for the project with the name project.jar,
+    == where project is replaced with the name of the project.
+    == This jar is built to the target.install directory.
+    =========================================================================-->
+  <target name="build" depends="compile, resource, jar.check, keygen" unless="jar.uptodate" description="Run a full build">
+    <mkdir dir="${target.install}"/>
+    <jar jarfile="${target.install}/${ant.project.name}.jar" manifest="${target.classes}/org/crosswire/flashcards/flashcards.manifest">
+      <fileset dir="${target.classes}"/>
+      <fileset dir="${font.dir}"/>
+    </jar>
+    <jar jarfile="${target.install}/${ant.project.name}_ws.jar" manifest="${target.classes}/org/crosswire/flashcards/flashcards.manifest">
+      <fileset dir="${target.classes}"/>
+      <fileset dir="${font.dir}"/>
+      <fileset dir="${source.root}" includes="lessons/**/*"/>
+    </jar>
+    <copy todir="${target.install}">
+      <fileset dir="${source.root}/app/webstart">
+        <include name="Flashcards.jnlp"/>
+        <include name="*.gif"/>
+      </fileset>
+    </copy>
+
+    <signjar
+          storepass="${keystore.pswd}"
+          alias="${keystore.alias}"
+          keystore="${keystore.file}"
+          keypass="${keystore.pswd}"
+          jar="${target.install}/${ant.project.name}.jar"/>
+    <signjar
+          storepass="${keystore.pswd}"
+          alias="${keystore.alias}"
+          keystore="${keystore.file}"
+          keypass="${keystore.pswd}"
+          jar="${target.install}/${ant.project.name}_ws.jar"/>
+  </target>
+  <target name="jar.check">
+    <uptodate property="jar.uptodate"
+        targetfile="${target.install}/${ant.project.name}.jar">
+      <srcfiles dir="${target.classes}"/>
+    </uptodate>
+  </target>
+
+  <target name="resource" depends="resource.check, keygen" unless="resource.uptodate" description="Run a full build">
+    <mkdir dir="${target.install}"/>
+    <jar jarfile="${target.install}/lessons.jar">
+      <fileset dir="${source.root}" includes="lessons/**/*"/>
+    </jar>
+    <signjar
+          storepass="${keystore.pswd}"
+          alias="${keystore.alias}"
+          keystore="${keystore.file}"
+          keypass="${keystore.pswd}"
+          jar="${target.install}/lessons.jar"/>
+  </target>
+  <target name="resource.check">
+    <uptodate property="resource.uptodate"
+        targetfile="${target.install}/lessons.jar">
+      <srcfiles dir="${source.res}/lessons"/>
+    </uptodate>
+  </target>
+
+  <!--=======================================================================
+    == Compile all the java files under source.path into class files.
+    == Make sure that all the resources in those directories make it over too.
+    =========================================================================-->
+  <target name="compile" description="Compile the source">
+    <mkdir dir="${target.classes}"/>
+    <javac debug="on"
+           srcdir="${source.java.common}"
+           includes="**/*.java"
+           destdir="${target.classes}"
+           source="1.4">
+      <exclude name="**/migrate/*"/>
+    </javac>
+    <javac debug="on"
+           srcdir="${source.java}"
+           includes="**/*.java"
+           destdir="${target.classes}"
+           source="1.4">
+      <exclude name="**/migrate/*"/>
+    </javac>
+    <!-- Copy the resources to the proper org/crosswire directory.
+      == The path separator could be either / or \
+      -->
+    <copy todir="${target.classes}" includeEmptyDirs="false" >
+<!--      <mapper type="regexp" from=".*[\\/](org[\\/].*)" to="\1"/>
+-->      <fileset dir="${source.java}">
+        <patternset refid="java.non.compile"/>
+        <exclude name="**/*Test*"/>
+      </fileset>
+    </copy>
+  </target>
+
+  <!--=======================================================================
+    == A keystore is needed to sign jars.
+    == It does not need to be build very often and can be shared.
+    =========================================================================-->
+  <target name="keygen"
+          depends="keygen.check"
+          unless="keygen.uptodate"
+          description="Generates a key for use in signing the JARs">
+    <echo message="Generating keystore for signing jars"/>
+    <genkey alias="${keystore.alias}"
+          storepass="${keystore.pswd}"
+          keystore="${keystore.file}">
+      <dname>
+        <param name="CN" value="The CrossWire Bible Society"/>
+        <param name="OU" value="FlashCards"/>
+        <param name="O" value="Crosswire.org"/>
+      </dname>
+    </genkey>
+  </target>
+  <target name="keygen.check" description="Check the keystore is there">
+    <available property="keygen.uptodate" file="${keystore.file}"/>
+  </target>
+</project>

Added: trunk/fonts/GalSILB201.ttf
===================================================================
(Binary files differ)


Property changes on: trunk/fonts/GalSILB201.ttf
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/fonts/SILEOT.ttf
===================================================================
(Binary files differ)


Property changes on: trunk/fonts/SILEOT.ttf
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: trunk/micro/src/org/crosswire/flashcards/MicroLessonSet.java
===================================================================
--- trunk/micro/src/org/crosswire/flashcards/MicroLessonSet.java	2007-12-24 02:18:43 UTC (rev 144)
+++ trunk/micro/src/org/crosswire/flashcards/MicroLessonSet.java	2007-12-30 20:31:14 UTC (rev 145)
@@ -1,59 +1,59 @@
-/*
- * Distribution Licence:
- * FlashCard is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General Public License,
- * version 2 as published by the Free Software Foundation.
- * This program 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.
- * The License is available on the internet at:
- *     http://www.gnu.org/copyleft/gpl.html,
- * or by writing to:
- *     Free Software Foundation, Inc.
- *     59 Temple Place - Suite 330
- *     Boston, MA 02111-1307, USA
- *
- * Copyright: 2006 CrossWire Bible Society
- */
-package org.crosswire.flashcards;
-
-
-/**
- * A <code>LessonSet</code> is an ordered list of <code>Lesson</code>s.
- * The lessons are sorted by filename.
- * The lesson set also has a description which is useful for showing to a user
- * and a directory name where its Lessons are stored. This directory name is expected to be a relative
- * path and will be stored either in a jar or in the user's FlashCard directory.
- *
- * @author Troy A. Griffitts [scribe at crosswire dot org]
- */
-public class MicroLessonSet extends LessonSet {
-
-     public MicroLessonSet(String url) {
-          super(url);
-     }
-
-
-     /**
-      * Load this lesson set from persistent store named by the lesson set's <code>dirname</code>.
-      * This is the union of lessons in the Jar and in the user's flashcard home directory.
-      */
-     protected void load() {
-		for (int i = 0; true; i++) {
-			String path = getURL() + "/" + "lesson" + padInt(i) + ".flash";
-			try {
-				add(new MicroLesson(path));
-			}
-			catch (Exception e) { break; }
-		}
-     }
-
-	String padInt(int i) {
-		String ret = Integer.toString(i);
-		if (i < 100) ret = "0"+ret;
-		if (i < 10 ) ret = "0"+ret;
-		return ret;
-	}
-}
+/*
+ * Distribution Licence:
+ * FlashCard is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License,
+ * version 2 as published by the Free Software Foundation.
+ * This program 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.
+ * The License is available on the internet at:
+ *     http://www.gnu.org/copyleft/gpl.html,
+ * or by writing to:
+ *     Free Software Foundation, Inc.
+ *     59 Temple Place - Suite 330
+ *     Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2006 CrossWire Bible Society
+ */
+package org.crosswire.flashcards;
+
+
+/**
+ * A <code>LessonSet</code> is an ordered list of <code>Lesson</code>s.
+ * The lessons are sorted by filename.
+ * The lesson set also has a description which is useful for showing to a user
+ * and a directory name where its Lessons are stored. This directory name is expected to be a relative
+ * path and will be stored either in a jar or in the user's FlashCard directory.
+ *
+ * @author Troy A. Griffitts [scribe at crosswire dot org]
+ */
+public class MicroLessonSet extends LessonSet {
+
+     public MicroLessonSet(String url) {
+          super(url);
+     }
+
+
+     /**
+      * Load this lesson set from persistent store named by the lesson set's <code>dirname</code>.
+      * This is the union of lessons in the Jar and in the user's flashcard home directory.
+      */
+     protected void load() {
+		for (int i = 0; true; i++) {
+			String path = getURL() + "/" + "lesson" + padInt(i) + ".flash";
+			try {
+				add(new MicroLesson(path));
+			}
+			catch (Exception e) { break; }
+		}
+     }
+
+	String padInt(int i) {
+		String ret = Integer.toString(i);
+		if (i < 100) ret = "0"+ret;
+		if (i < 10 ) ret = "0"+ret;
+		return ret;
+	}
+}

Modified: trunk/src/org/crosswire/flashcards/FlashCard.java
===================================================================
--- trunk/src/org/crosswire/flashcards/FlashCard.java	2007-12-24 02:18:43 UTC (rev 144)
+++ trunk/src/org/crosswire/flashcards/FlashCard.java	2007-12-30 20:31:14 UTC (rev 145)
@@ -1,177 +1,177 @@
-/*
- * Distribution Licence:
- * FlashCard is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General Public License,
- * version 2 as published by the Free Software Foundation.
- * This program 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.
- * The License is available on the internet at:
- *     http://www.gnu.org/copyleft/gpl.html,
- * or by writing to:
- *     Free Software Foundation, Inc.
- *     59 Temple Place - Suite 330
- *     Boston, MA 02111-1307, USA
- *
- * Copyright 2006: CrossWire Bible Society
- */
-package org.crosswire.flashcards;
-
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-/**
- * A FlashCard has a front and a back. The front has the test
- * and the back has the answer.
- *
- * @author Troy A. Griffitts [scribe at crosswire dot org]
- * @author DM Smith [ dmsmith555 at yahoo dot com]
- */
-public class FlashCard {
-  private Hashtable original = new Hashtable();
-  private Hashtable values = new Hashtable();
-  private final String front = "front";
-  private final String back = "back";
-  private final String audioURL = "audioURL";
-  private final String imageURL = "imageURL";
-
-  /**
-   * Create a partial FlashCard.
-   * @param front
-   */
-  public FlashCard() {
-    this("", "");
-  }
-
-  /**
-   * Create a complete FlashCard
-   * @param front
-   * @param back
-   */
-  public FlashCard(String frontValue, String backValue) {
-    original.put(front, frontValue);
-    original.put(back, backValue);
-    reset();
-  }
-
-  /**
-   * Get a particular side of this FlashCard.
-   * This is useful to flip the cards.
-   * @param front
-   * @return the requested side
-   */
-  public String getSide(boolean frontside) {
-    if (frontside) {
-      return getFront();
-    }
-    return getBack();
-  }
-
-  /**
-   * @return Returns the back.
-   */
-  public String getBack() {
-    return (String)values.get(back);
-  }
-
-  /**
-   * @param newBack The back to set.
-   */
-  public void setBack(String newBack) {
-    values.put(back, newBack);
-  }
-
-  /**
-   * @return Returns the front.
-   */
-  public String getFront() {
-    return (String)values.get(front);
-  }
-
-  /**
-   * @param newFront The front to set.
-   */
-  public void setFront(String newFront) {
-    values.put(front, newFront);
-  }
-
-  public String getAudioURL() {
-    return (String) values.get(audioURL);
-  }
-
-  public void setAudioURL(String newAudioURL) {
-    values.put(audioURL, newAudioURL);
-  }
-
-  public String getImageURL() {
-    return (String) values.get(imageURL);
-  }
-
-  public void setImageURL(String newImageURL) {
-    values.put(imageURL, newImageURL);
-  }
-
-  /**
-   * Method reset
-   */
-  public void reset() {
-    hashCopy(values, original);
-  }
-
-  private static void hashCopy(Hashtable dest, Hashtable src) {
-    dest.clear();
-    for (Enumeration k = src.keys(); k.hasMoreElements();) {
-      String key = (String)k.nextElement();
-      dest.put(key, src.get(key));
-    }
-  }
-
-  /**
-   * Method isIncomplete
-   * @return boolean
-   */
-  public boolean isIncomplete() {
-    return (values.get(front) != null) && (values.get(back) != null);
-  }
-
-  /**
-   * Method setOriginal
-   */
-  public void setOriginal() {
-    hashCopy(original, values);
-  }
-
-  /**
-   * @return Returns whether this FlashCard has been modified.
-   */
-  protected boolean isModified() {
-    return !values.equals(original);
-  }
-
-  public Object clone() {
-    FlashCard n = new FlashCard();
-    hashCopy(n.original, original);
-    hashCopy(n.values, values);
-    return n;
-  }
-
-  /* (non-Javadoc)
-   * @see java.lang.Object#equals(java.lang.Object)
-   */
-  public boolean equals(Object obj) {
-    if (obj == this) {
-      return true;
-    }
-    if (! (obj instanceof FlashCard)) {
-      return false;
-    }
-    FlashCard otherCard = (FlashCard) obj;
-    return values.equals(otherCard.values);
-  }
-
-  public int compareTo(Object other) {
-      return getFront().compareTo(((FlashCard)other).getFront());
-  }
-}
+/*
+ * Distribution Licence:
+ * FlashCard is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License,
+ * version 2 as published by the Free Software Foundation.
+ * This program 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.
+ * The License is available on the internet at:
+ *     http://www.gnu.org/copyleft/gpl.html,
+ * or by writing to:
+ *     Free Software Foundation, Inc.
+ *     59 Temple Place - Suite 330
+ *     Boston, MA 02111-1307, USA
+ *
+ * Copyright 2006: CrossWire Bible Society
+ */
+package org.crosswire.flashcards;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * A FlashCard has a front and a back. The front has the test
+ * and the back has the answer.
+ *
+ * @author Troy A. Griffitts [scribe at crosswire dot org]
+ * @author DM Smith [ dmsmith555 at yahoo dot com]
+ */
+public class FlashCard {
+  private Hashtable original = new Hashtable();
+  private Hashtable values = new Hashtable();
+  private final String front = "front";
+  private final String back = "back";
+  private final String audioURL = "audioURL";
+  private final String imageURL = "imageURL";
+
+  /**
+   * Create a partial FlashCard.
+   * @param front
+   */
+  public FlashCard() {
+    this("", "");
+  }
+
+  /**
+   * Create a complete FlashCard
+   * @param front
+   * @param back
+   */
+  public FlashCard(String frontValue, String backValue) {
+    original.put(front, frontValue);
+    original.put(back, backValue);
+    reset();
+  }
+
+  /**
+   * Get a particular side of this FlashCard.
+   * This is useful to flip the cards.
+   * @param front
+   * @return the requested side
+   */
+  public String getSide(boolean frontside) {
+    if (frontside) {
+      return getFront();
+    }
+    return getBack();
+  }
+
+  /**
+   * @return Returns the back.
+   */
+  public String getBack() {
+    return (String)values.get(back);
+  }
+
+  /**
+   * @param newBack The back to set.
+   */
+  public void setBack(String newBack) {
+    values.put(back, newBack);
+  }
+
+  /**
+   * @return Returns the front.
+   */
+  public String getFront() {
+    return (String)values.get(front);
+  }
+
+  /**
+   * @param newFront The front to set.
+   */
+  public void setFront(String newFront) {
+    values.put(front, newFront);
+  }
+
+  public String getAudioURL() {
+    return (String) values.get(audioURL);
+  }
+
+  public void setAudioURL(String newAudioURL) {
+    values.put(audioURL, newAudioURL);
+  }
+
+  public String getImageURL() {
+    return (String) values.get(imageURL);
+  }
+
+  public void setImageURL(String newImageURL) {
+    values.put(imageURL, newImageURL);
+  }
+
+  /**
+   * Method reset
+   */
+  public void reset() {
+    hashCopy(values, original);
+  }
+
+  private static void hashCopy(Hashtable dest, Hashtable src) {
+    dest.clear();
+    for (Enumeration k = src.keys(); k.hasMoreElements();) {
+      String key = (String)k.nextElement();
+      dest.put(key, src.get(key));
+    }
+  }
+
+  /**
+   * Method isIncomplete
+   * @return boolean
+   */
+  public boolean isIncomplete() {
+    return (values.get(front) != null) && (values.get(back) != null);
+  }
+
+  /**
+   * Method setOriginal
+   */
+  public void setOriginal() {
+    hashCopy(original, values);
+  }
+
+  /**
+   * @return Returns whether this FlashCard has been modified.
+   */
+  protected boolean isModified() {
+    return !values.equals(original);
+  }
+
+  public Object clone() {
+    FlashCard n = new FlashCard();
+    hashCopy(n.original, original);
+    hashCopy(n.values, values);
+    return n;
+  }
+
+  /* (non-Javadoc)
+   * @see java.lang.Object#equals(java.lang.Object)
+   */
+  public boolean equals(Object obj) {
+    if (obj == this) {
+      return true;
+    }
+    if (! (obj instanceof FlashCard)) {
+      return false;
+    }
+    FlashCard otherCard = (FlashCard) obj;
+    return values.equals(otherCard.values);
+  }
+
+  public int compareTo(Object other) {
+      return getFront().compareTo(((FlashCard)other).getFront());
+  }
+}




More information about the sword-cvs mailing list