import java.util.*; import java.net.*; import java.applet.*; import java.awt.*; import java.io.*; abstract class ShopPanel { static Vector products = new Vector(100); static String newPrices = ""; static String ID = ""; static String item = ""; static Double price = new Double(0.0); static double subtotal = 0.0; static int limit = 0; static int numInList = 0; static String substring = ""; static String shipping = ""; static String[] resetID; //to store reset values; a Vector class messes up static Integer[] resetNum; static String[] resetItem; static Double[] resetPrice; static String[] resetShipping; static int resetNumItems; static ShopFrame shopFrame = new ShopFrame(); static String frameTitle; static Boolean firstTime = new Boolean(true); static Boolean dataNotRead = new Boolean(true); static String temp = ""; static Integer currentNumber = new Integer(0); static String codebase; static String documentBase; static int start; static int length; static StringBuffer buffer; static Color backColor = new Color(255,50,50); static app parent; static TextField itemChosen = new TextField(); static List listOfProducts = new List(); static TextField subTotal = new TextField("$ 0.0"); static Label subLabel = new Label(" Subtotal . . ."); static Button clearCart = new Button("Clear Cart"); static Button help = new Button("Help"); static Button addItem = new Button("More"); static Button addTenItems = new Button("Ten More");; static Button removeItem = new Button("Less"); static Button removeTenItems = new Button("Ten Less"); static Button finalizeOrder = new Button("Checkout ..."); static Button reset = new Button("Reset"); static Button up = new Button("Up"); static Button down = new Button("Down"); static Font small = new Font("Courier",Font.PLAIN,10); static Font medium = new Font("TimesRoman",Font.PLAIN,12); static Font big = new Font("Dialog",Font.BOLD,20); static Font mediumBold = new Font("TimesRoman",Font.BOLD,13); static Font moneyBold = new Font("Courier",Font.BOLD,13); static long startTime; static AppletContext ac; static void formPanelElements() { shopFrame.setBounds(154,110,343,182); //also resized elsewhere shopFrame.setLayout(null); //if you use layout manager, you can't get background color clearCart.setFont(medium); clearCart.setBackground(Color.yellow); clearCart.setBounds(220,64,66,15); help.setFont(medium); help.setBackground(Color.yellow); help.setBounds(290,64,41,15); up.setFont(medium); up.setBounds(225,82,38,15); up.setBackground(Color.yellow); down.setFont(medium); down.setBackground(Color.yellow); down.setBounds(258,82,67,15); addItem.setFont(medium); addItem.setBackground(Color.yellow); addItem.setBounds(225,99,38,15); addTenItems.setFont(medium); addTenItems.setBackground(Color.yellow); addTenItems.setBounds(258,99,67,15); removeItem.setFont(medium); removeItem.setBackground(Color.yellow); removeItem.setBounds(225,116,38,15); removeTenItems.setBackground(Color.yellow); removeTenItems.setFont(medium); removeTenItems.setBounds(258,116,67,15); finalizeOrder.setFont(mediumBold); finalizeOrder.setBackground(Color.yellow); finalizeOrder.setBounds(218,134,75,16); reset.setFont(small); reset.setBackground(Color.yellow); reset.setBounds(297,134,35,16); reset.disable(); listOfProducts.setFont(small); listOfProducts.setBackground(Color.white); listOfProducts.setBounds(10,58,200,74); subTotal.setFont(moneyBold); subTotal.setBackground(Color.white); subTotal.setEditable(false); subTotal.setBounds(90,132,120,20); subLabel.setFont(mediumBold); subLabel.setBackground(new Color(160,160,215)); subLabel.setBounds(12,132,78,20); itemChosen.setFont(big); itemChosen.setBackground(Color.white); itemChosen.setEditable(false); itemChosen.setBounds(10,28,320,30); shopFrame.setFont(small); shopFrame.setBackground(new Color(255,50,50)); //also set in ShopFrame } static void init() { if(products.size() > 2) upFrame(); } static void initValues(Applet p) { parent = (app)p; init(); if(firstTime.booleanValue()) { formPanelElements(); //Part 1 - simulates a constructor for ShopPanel; note shopFrame is initialized in ShopPanel declaration shopFrame.formPanel(); //Part 2 - simulates a constructor for ShopPanel firstTime = new Boolean(false); } codebase = parent.getCodeBase().toString(); documentBase = parent.getDocumentBase().toString(); start = new Integer(parent.getParameter("start")).intValue(); length = new Integer(parent.getParameter("length")).intValue(); shopFrame.setTitle("Infinite Stores"); ac = parent.getAppletContext(); } static void upFrame() { shopFrame.requestFocus(); shopFrame.toFront(); shopFrame.show(); } static void prod(String iD, String it, String pr, String sh) { upFrame(); ID = new String(iD); price=Double.valueOf(pr); sh = new String(parent.getDocumentBase().toString().substring(start,start + length)); prod(ID, it, price, sh, new Integer(1)); shopFrame.setSize(343,182); //Netscape needs it repeated here } static void prod(String ID, String it, Double price, String sh, Integer purchaseAmount) { temp = it; if( (temp.length() > 21) && (temp.charAt(21) != '.') ) item = temp.substring(0,20) + " ..."; //second condition prevents double ...s at reset else item = temp; shipping = new String(sh); reset.disable(); if(products.size() > 0) { for(int i = 0; i < products.size()/5; i++) { if(products.elementAt(5*i).equals(ID)) { products.setElementAt(new Integer(((Integer)products.elementAt(5*i + 1)).intValue() + purchaseAmount.intValue()), 5*i + 1); updateTheList(i,false); updateSubtotal(); return; } } } products.addElement((String)ID); //new purchase products.addElement(purchaseAmount); products.addElement((String)item); products.addElement((Double)price); products.addElement((String)shipping); numInList++; //count in class List doesn't work updateTheList(products.size()/5 - 1,true); updateSubtotal(); } static void updateTheList(int row, boolean newItem) { String temp1 = products.elementAt(5*row+1).toString() + " "; temp1 += (String)products.elementAt(5*row+2) + " "; String price = "$" + currency((Double)products.elementAt(5*row+3)); if(temp1.length() > (28 - price.length())) temp1 = temp1.substring(0,(25 - price.length())) + "..."; int spaces = 29 - temp1.length() - price.length(); for (int j = 0; j < spaces; j++) { temp1 += " "; } temp1 += price; if(newItem) { listOfProducts.addItem(temp1); row = numInList - 1; } else listOfProducts.replaceItem(temp1,row); listOfProducts.select(row); listOfProducts.makeVisible(row); updateHeading(); //the previous two commands don't trigger an event, so need this } static String currency(Double money) { String temp = money.toString(); if((temp.indexOf(".") > 0) && (temp.indexOf(".") == (temp.length() - 2))) { temp = temp + "0"; } else if((temp.indexOf(".") > 0) && (temp.indexOf(".") < (temp.length() - 2))) { temp = temp.substring(0,temp.indexOf(".") + 3); } return temp; } static void clearCart() { if(products.size() == 0) return; products.removeAllElements(); listOfProducts.select(numInList - 1); //doesn't delete first item in IE if there are three items, and first item happens to be selected, so select another for(int i = 0; i < numInList ; i++) { listOfProducts.delItem(0); } itemChosen.setText(""); numInList = 0; //count in class List doesn't work } static void updateHeading() { if(listOfProducts.getSelectedItem() != null) { itemChosen.setText(listOfProducts.getSelectedItem().substring(0,listOfProducts.getSelectedItem().indexOf('$') + 1) + String.valueOf( currency( new Double( ((Integer)products.elementAt(listOfProducts.getSelectedIndex()*5 + 1)).intValue() * ((Double)products.elementAt(listOfProducts.getSelectedIndex()*5 + 3)).doubleValue() ) ) )); } else itemChosen.setText(""); } static void updateSubtotal() { subtotal = 0.0; for(int i = 0; i < products.size()/5; i++) { subtotal += ((Double)products.elementAt(5*i + 3)).doubleValue() * ((Integer)products.elementAt(5*i + 1)).intValue(); } substring = "$" + currency(new Double(subtotal)); limit = 13 - substring.length(); for(int i = 0; i < limit; i++) substring = " " + substring; subTotal.setText(substring); } static void up() { if(listOfProducts.getSelectedIndex() > 0) { listOfProducts.select(listOfProducts.getSelectedIndex() - 1); updateHeading(); } } static void down() { if( (listOfProducts.getSelectedIndex() >= 0) && (listOfProducts.getSelectedIndex() < numInList) ) { listOfProducts.select(listOfProducts.getSelectedIndex() + 1); updateHeading(); } } static void addAnItem(Integer m) { if(listOfProducts.getSelectedIndex() >= 0) { products.setElementAt(new Integer(((Integer)products.elementAt(listOfProducts.getSelectedIndex()*5 + 1)).intValue() + m.intValue()),listOfProducts.getSelectedIndex()*5 + 1); updateTheList(listOfProducts.getSelectedIndex(),false); updateSubtotal(); } } static void removeAnItem(Integer m) { limit = listOfProducts.getSelectedIndex(); if(limit >= 0) { if( (((Integer)products.elementAt(5*limit + 1)).intValue()-m.intValue()) > 0) //decrement { products.setElementAt(new Integer(((Integer)products.elementAt(5*limit + 1)).intValue() - m.intValue()),5*limit + 1); updateTheList(listOfProducts.getSelectedIndex(),false); } else //remove completely { products.removeElementAt(5*limit + 4); //be sure to remove elements from the top first, or else renumbering messes you up products.removeElementAt(5*limit + 3); products.removeElementAt(5*limit + 2); products.removeElementAt(5*limit + 1); products.removeElementAt(5*limit); if(limit > 0) listOfProducts.select(limit - 1); //Netscape won't transfer focus properly, so help it else if(numInList > 1) listOfProducts.select(1); listOfProducts.remove(limit); numInList--; itemChosen.setText(""); updateHeading(); //another item will be selected, but it needs to be echoed into heading } updateSubtotal(); } } static String orderString() { int size = products.size(); //to prepare for reset resetID = new String[size]; //dimension may be too large, but not by much; Vector class messes up resetNum = new Integer[size]; resetItem = new String[size]; resetPrice = new Double[size]; resetShipping = new String[size]; String temp = ""; double total = 0; int currentNum = currentNumber.intValue(); temp = "?VENDOR=" + eliminateSpaces(codebase) + "&";; temp += "CURRNUM=" + currentNum + "&"; int i = 0; while(products.size()/5 > 0) { String tryMore = ""; tryMore += "I" + i + "=" + eliminateSpaces((String)products.elementAt(0)) + "&"; tryMore += "Q" + i + "=" + products.elementAt(1) + "&"; tryMore += "D" + i + "=" + eliminateSpaces((String)products.elementAt(2)) + "&"; tryMore += "P" + i + "=" + currency((Double)products.elementAt(3)) + "&"; tryMore += "S" + i + "=" + eliminateSpaces((String)products.elementAt(4)) + "&"; i++; if(temp.concat(tryMore).length() < 900) //900 seems OK for Explorer { currentNum++; temp += tryMore; total = total + ((Integer)products.elementAt(1)).intValue()*((Double)products.elementAt(3)).doubleValue(); resetID[i - 1] = (String)products.elementAt(0); //prepare for possible reset resetNum[i - 1] = (Integer)products.elementAt(1); resetItem[i - 1] = (String)products.elementAt(2); resetPrice[i - 1] = (Double)products.elementAt(3); resetShipping[i - 1] = (String)products.elementAt(4); resetNumItems = i - 1; //end prepare for possible reset listOfProducts.select(0); removeAnItem(new Integer(30000)); //make sure to get them all } else { break; } currentNumber = new Integer(currentNum); } if(products.size()/5 > 0) temp += "More=true&"; else { temp += "More=false&"; itemChosen.setText(" Reset restores your order"); } temp += "NUM=" + i + "&"; temp += "TOT=" + currency(new Double(total)) + "&"; reset.enable(); return temp; } static String eliminateSpaces(String s) { String temp = s; while(temp.indexOf(' ') > 0) { temp = temp.substring(0,temp.indexOf(' ')) + "%20" + temp.substring(temp.indexOf(' ') + 1); } return temp; } static void resetOrder() { reset.disable(); for(int i = 0; i < resetNumItems + 1; i++) { prod(resetID[i],resetItem[i],resetPrice[i],resetShipping[i],resetNum[i]); } } static void pause(int time) { startTime = System.currentTimeMillis(); while(System.currentTimeMillis() < startTime + time) { //infinite loop: create delay to bring up shopframe AFTER orderFrame is displayed } } static void closeWindow() { itemChosen.setText(" 'Clear Cart' closes window"); pause(4000); updateHeading(); } static void orderJump() { if(parent.isActive()) { try { ac.showDocument(new URL("http://209.87.142.42/order2.asp" + orderString()),"_blank"); //Naming the window _order creates a new window if it doesn't exist, or uses the existing one if it does. Very nice. However, the order window can then get lost in the bottom or the back, and cannot then be brought back easily. Too bad. } catch (MalformedURLException me) {} } else { itemChosen.setText(" Finalize at Infinite Stores"); pause(4000); updateHeading(); } } static void helpJump() { if(parent.isActive()) { try { ac.showDocument(new URL("http://209.87.142.42/help.htm")); } catch (MalformedURLException me) {} } else { itemChosen.setText(" Available at Infinite Stores"); pause(4000); updateHeading(); } } }