// Html.java (C)Copyright Bernd Noetscher 1999

import java.awt.*;
import java.applet.*;
import java.util.*;
import java.net.*;
import java.awt.event.*;

public class Html extends Applet
{
Font oFont;
Color oForeColor;
Color oBackColor;
String sFontname;
int nSize;
boolean bItalic;
boolean bBold;
boolean bUnderline;
boolean bUL;
boolean bOL;
boolean bTable;

int nTableCols;
int nTableWidth;
int nRowHeight;
int nColWidth;

int nCounter = 0;
int nStart_x;
int nStart_y;
int nPos_x;
int nPos_y;
Stack oFontStack;


/*

StartString mit Standard für FONT etc. wird ausgeführt vor eigentlichem Html

Stackmäßig die Keywords bearbeiten
Umlaute müssen umgesetzt werden
*/

public void init()
{
setLayout(new BorderLayout());
setSize(750,400);

}

public void paint(Graphics g)
{
String sStri = "";

sStri = sStri + "<FONT FACE='Arial,Helvetica'><FONT COLOR='#FF0000'><FONT SIZE=10>";

sStri = sStri + "<BODY BGCOLOR='#FFFFCC' BACKGROUND='M005g83c.jpg'>";
/*
sStri = sStri + "<TABLE COLS=2 WIDTH='36%'>";
sStri = sStri + "<TR>";
sStri = sStri + "<TD WIDTH='199'>spalte1</TD>";
sStri = sStri + "<TD><B>spalte2</B></TD>";
sStri = sStri + "</TR>";
sStri = sStri + "<TR>";
sStri = sStri + "<TD>xxxxx</TD>";
sStri = sStri + "<TD>yyyyyyy</TD>";
sStri = sStri + "</TR>";
sStri = sStri + "</TABLE>";

sStri = sStri + "<UL>";
sStri = sStri + "<LI>";
sStri = sStri + "<FONT FACE='Arial,Helvetica'><FONT COLOR='#FF0000'><FONT SIZE=+4>aa</FONT></FONT></FONT></LI>";

sStri = sStri + "<LI>";
sStri = sStri + "<FONT FACE='Arial,Helvetica'><FONT COLOR='#FF0000'><FONT SIZE=+4>bb</FONT></FONT></FONT></LI>";

sStri = sStri + "<LI>";
sStri = sStri + "<FONT FACE='Arial,Helvetica'><FONT COLOR='#FF0000'><FONT SIZE=+4>cc</FONT></FONT></FONT></LI>";
sStri = sStri + "</UL>";


sStri = sStri + "<OL>";
sStri = sStri + "<LI>";
sStri = sStri + "<FONT FACE='Arial,Helvetica'><FONT COLOR='#FF0000'><FONT SIZE=+4>aa</FONT></FONT></FONT></LI>";

sStri = sStri + "<LI>";
sStri = sStri + "<FONT FACE='Arial,Helvetica'><FONT COLOR='#FF0000'><FONT SIZE=+4>bb</FONT></FONT></FONT></LI>";

sStri = sStri + "<LI>";
sStri = sStri + "<FONT FACE='Arial,Helvetica'><FONT COLOR='#FF0000'><FONT SIZE=+4>cc</FONT></FONT></FONT></LI>";
sStri = sStri + "</OL>";

sStri = sStri + "<HR WIDTH='100%'>";
*/
sStri = sStri + "<BR><IMG SRC='Baer.JPG' HEIGHT=75 WIDTH=200>";

sStri = sStri + "<FONT FACE='Arial,Helvetica'><FONT COLOR='#FF0000'><FONT SIZE=12>Greetings! Welcome to the new 1999 Cadillac Warehouse";

sStri = sStri + "<FONT FACE='Arial,Helvetica'><FONT COLOR='#FF00FF'><FONT SIZE=8>";

sStri = sStri + "<P><FONT FACE='Courier New,Courier'>a super dealer for a super deal on the Web.&nbsp; Our premise is simple,</FONT><I> - pick the options</I> calculate <BR>";
sStri = sStri + "<B>the cost and compare the awesome savings. There's no sales hassle or pressure. As one of the top Cadillac dealers</B> <BR>";
sStri = sStri + "<BR><U>in the United States, we assure you superior customer service and</U> satisfaction.&nbsp;<I> From a single</I><B> mouse</B> click <BR>";
sStri = sStri + "<BR><FONT COLOR='#FFFFFF'>to delivery of a brand new or pre-owned Cadillac to your front door, the process is fast and easy. </FONT>Our buying power <BR>";
sStri = sStri + "<BR><FONT COLOR='#FF6600'>is unsurpassed, so we can offer you one of the best deals in the nation<FONT FACE='Times New Roman,Times'> - we dare you to compare! <BR>";
sStri = sStri + "</FONT>It's easy to get started, just click on the model of your choice.</FONT> <BR>";

sStri = sStri + "<FONT COLOR='#009900'>Thank you.</FONT> ";

sStri = sStri + "<P><FONT COLOR='#009900'>Goodbye!</FONT> ";
/*
sStri = sStri + "<P>&lt;";
sStri = sStri + "<BR>>";
sStri = sStri + "<BR>&amp;";
sStri = sStri + "<BR>;";
sStri = sStri + "<BR>&nbsp;";
*/
paintHtml(g, sStri);
}

public void paintHtml(Graphics g, String sSource)
{
oFont = g.getFont();
sFontname = oFont.getName();
nSize = 10;//oFont.getSize();
oForeColor = g.getColor();
oBackColor = new Color(0xFF,0xFF,0xFF);
bItalic = oFont.isItalic();
bBold = oFont.isBold();
bUnderline = false;
bUL = false;
bOL = false;
bTable = false;
nTableCols = 0;
nTableWidth = 0;
nRowHeight = 0;
nColWidth = 0;

nStart_x = 10;
nStart_y = 20;
nPos_x = 0;
nPos_y = 0;
oFontStack = new Stack();

String sHtml = sSource;
String sCode = sSource;
int nStart = 0;
while(sHtml.length() > 0){
sCode = nextCode(sHtml);
if(sCode.length() > 0){
if(runCode(g, sCode) == true){
nStart += sCode.length() + 2;
} else {
nStart += sCode.length();
}
sHtml = sSource.substring(nStart);
} else {
break;
}
}
}

public String nextCode(String sSource)
{
String sRet = "";

StringTokenizer Start = new StringTokenizer(sSource, "<");
if(Start.hasMoreTokens() == true){
sRet = Start.nextToken();
if(sSource.startsWith("<")){
StringTokenizer End = new StringTokenizer(sRet, ">");
if(End.hasMoreTokens() == true){
sRet = End.nextToken();
} else {
sRet = "";
}
}
}
return(sRet);
}

public String macheUmlaute(String sSource)
{
String sRet = "";
String sTest = "";
String sTest2 = "";
int nCounter = 0;

sTest2 = sSource;
StringTokenizer Start = new StringTokenizer(sSource, "&");
while(Start.hasMoreTokens() == true){

sTest = Start.nextToken();

if(sTest2.startsWith("&")){

StringTokenizer End = new StringTokenizer(sTest, ";");
if(End.hasMoreTokens() == true){
sTest = End.nextToken();
nCounter = nCounter + sTest.length() + 2;
} else {
sTest = "";
nCounter = nCounter + sTest.length() + 1;
}

if(sTest.compareTo("auml") == 0){
sTest = "ä";
} else if(sTest.compareTo("uuml") == 0){
sTest = "ü";
} else if(sTest.compareTo("ouml") == 0){
sTest = "ö";
} else if(sTest.compareTo("Auml") == 0){
sTest = "Ä";
} else if(sTest.compareTo("Uuml") == 0){
sTest = "Ü";
} else if(sTest.compareTo("Ouml") == 0){
sTest = "Ö";
} else if(sTest.compareTo("szlig") == 0){
sTest = "ß";
} else if(sTest.compareTo("lt") == 0){
sTest = "<";
} else if(sTest.compareTo("amp") == 0){
sTest = "&";
} else if(sTest.compareTo("nbsp") == 0){
sTest = "";
}
} else {
nCounter = nCounter + sTest.length();
}

sTest2 = sSource.substring(nCounter);
sRet = sRet + sTest;
Start = new StringTokenizer(sTest2, "&");
}
return(sRet);
}

public boolean runCode(Graphics g, String sSource)
{
return(runCode(g, sSource, true));
}

public boolean runCode(Graphics g, String sSource, boolean bSaveOldValue)
{
boolean bRet = false;

if(sSource.compareTo("I") == 0){
bItalic = true;
bRet = true;
} else if(sSource.compareTo("/I") == 0){
bItalic = false;
bRet = true;
} else if(sSource.compareTo("B") == 0){
bBold = true;
bRet = true;
} else if(sSource.compareTo("/B") == 0){
bBold = false;
bRet = true;
} else if(sSource.compareTo("U") == 0){
bUnderline = true;
bRet = true;
} else if(sSource.compareTo("/U") == 0){
bUnderline = false;
bRet = true;
} else if(sSource.compareTo("P") == 0){
nPos_x = 0;
nPos_y += 2 + 2 * (this.getFontMetrics(g.getFont()).getHeight());;
bRet = true;
} else if(sSource.compareTo("BR") == 0){
nPos_x = 0;
nPos_y += 2 + (this.getFontMetrics(g.getFont()).getHeight());;
bRet = true;
} else if(sSource.compareTo("/UL") == 0){
bUL = false;
bRet = true;
} else if(sSource.compareTo("UL") == 0){
bUL = true;
nCounter = 0;
bRet = true;
} else if(sSource.compareTo("/OL") == 0){
bOL = false;
bRet = true;
} else if(sSource.compareTo("OL") == 0){
bOL = true;
nCounter = 0;
bRet = true;
} else if(sSource.compareTo("/TR") == 0){
nPos_x = 0;
nPos_y += 2 + (this.getFontMetrics(g.getFont()).getHeight());;
nRowHeight = 0;
bRet = true;
} else if(sSource.compareTo("TR") == 0){
bRet = true;
} else if(sSource.compareTo("/TD") == 0){
nPos_x += nColWidth;
bRet = true;
} else if(sSource.startsWith("TD")){
bRet = true;
if(sSource.startsWith("TD ")){
sSource = sSource.substring(new String("TD ").length());

if(sSource.startsWith("WIDTH=")){
bRet = true;

int nWert = 0;

sSource = sSource.substring(new String("WIDTH=").length());
sSource = sSource.substring(1, sSource.length() - 1);
if(sSource.endsWith("%")){
sSource = sSource.substring(0, sSource.length() - 1);
nWert = nTableWidth / 100 * new Integer(sSource).intValue();
} else {
nWert = new Integer(sSource).intValue();
}
nColWidth = nWert;
}

if(sSource.startsWith("HEIGHT=")){
bRet = true;

int nWert = 0;

sSource = sSource.substring(new String("HEIGHT=").length());
sSource = sSource.substring(1, sSource.length() - 1);
if(sSource.endsWith("%")){
} else {
nWert = new Integer(sSource).intValue();
}
nRowHeight = nWert;
}
}

} else if(sSource.compareTo("/LI") == 0){
if(bUL == true){
nPos_x = 0;
nPos_y += 2 + (this.getFontMetrics(g.getFont()).getHeight());;
bRet = true;
}
if(bOL == true){
nPos_x = 0;
nPos_y += 2 + (this.getFontMetrics(g.getFont()).getHeight());;
bRet = true;
}
} else if(sSource.compareTo("LI") == 0){
if(bUL == true){
nCounter++;
nPos_x += 15;
g.setColor(Color.black);
g.fillArc(nStart_x + nPos_x - 10, nStart_y + nPos_y - 8, 4, 4, 0, 360);
g.setColor(oForeColor);
bRet = true;
}
if(bOL == true){
nCounter++;
nPos_x += 15;
g.setColor(Color.black);
g.drawString("" + nCounter + ".", nStart_x + nPos_x - 15, nStart_y + nPos_y - 2);
g.setColor(oForeColor);
bRet = true;
}
} else if(sSource.compareTo("/FONT") == 0 && oFontStack.empty() == false){
bRet = true;
String sStri = (String) oFontStack.pop();
runCode(g, sStri, false);
} else if(sSource.startsWith("FONT ")){
sSource = sSource.substring(new String("FONT ").length());
if(sSource.startsWith("FACE=")){
if(bSaveOldValue == true){
saveOldValue(sSource); // für Undo
}
bRet = true;
sSource = sSource.substring(new String("FACE=").length());
sSource = sSource.substring(new String("'").length());
if(sSource.regionMatches(0, "Arial", 0, new String("Arial").length())){
sFontname = "Helvetica";
} else if(sSource.regionMatches(0, "Helvetica", 0, new String("Helvetica").length())){
sFontname = "Helvetica";
} else if(sSource.regionMatches(0, "Courier New", 0, new String("Courier New").length())){
sFontname = "Courier";
} else if(sSource.regionMatches(0, "Courier", 0, new String("Courier").length())){
sFontname = "Courier";
} else if(sSource.regionMatches(0, "Times New Roman", 0, new String("Times New Roman").length())){
sFontname = "TimesRoman";
} else if(sSource.regionMatches(0, "Times", 0, new String("Times").length())){
sFontname = "TimesRoman";
}
} else if(sSource.startsWith("COLOR=")){
if(bSaveOldValue == true){
saveOldValue(sSource); // für Undo
}
bRet = true;
sSource = sSource.substring(new String("COLOR=").length());
sSource = sSource.substring(new String("'#").length());
int nRed = getHexNum(sSource.substring(0, 2));
int nBlue = getHexNum(sSource.substring(2, 4));
int nGreen = getHexNum(sSource.substring(4, 6));
oForeColor = new Color(nRed, nBlue, nGreen);
} else if(sSource.startsWith("SIZE=")){
if(bSaveOldValue == true){
saveOldValue(sSource); // für Undo
}
bRet = true;
sSource = sSource.substring(new String("SIZE=").length());
if(sSource.startsWith("+")){
sSource = sSource.substring(new String("+").length());
nSize += new Integer(sSource).intValue();
} else if(sSource.startsWith("-")){
sSource = sSource.substring(new String("-").length());
nSize -= new Integer(sSource).intValue();
} else {
nSize = new Integer(sSource).intValue();
}
}
} else if(sSource.startsWith("IMG ")){
sSource = sSource.substring(new String("IMG ").length());
if(sSource.startsWith("SRC=")){
bRet = true;

String sImage = "";
int nHeight = 0;
int nWidth = 0;
StringTokenizer Start;

sSource = sSource.substring(new String("SRC=").length());
sSource = sSource.substring(new String("'").length());

Start = new StringTokenizer(sSource, "'");
if(Start.hasMoreTokens() == true){
sImage = Start.nextToken();
}

sSource = sSource.substring(sImage.length() + new String("' ").length());
if(sSource.startsWith("HEIGHT=")){
sSource = sSource.substring(new String("HEIGHT=").length());

Start = new StringTokenizer(sSource);
if(Start.hasMoreTokens() == true){
String sStri= Start.nextToken();
nHeight = new Integer(sStri).intValue();
sSource = sSource.substring(sStri.length() + 1);
}
}
if(sSource.startsWith("WIDTH=")){
sSource = sSource.substring(new String("WIDTH=").length());

Start = new StringTokenizer(sSource, ">");
if(Start.hasMoreTokens() == true){
nWidth = new Integer(Start.nextToken()).intValue();
}
}

try {
Image Imag = this.getImage(new URL(this.getCodeBase() + sImage));
if(Imag != null){
MediaTracker Media = new MediaTracker(this);
Media.addImage(Imag, 0);
try {
Media.waitForID(0);
} catch (InterruptedException e) {
System.err.println(e);
}
if(nWidth == 0 && nHeight == 0){
g.drawImage(Imag, nStart_x + nPos_x, nStart_y + nPos_y, null);
} else {
g.drawImage(Imag, nStart_x + nPos_x, nStart_y + nPos_y - (this.getFontMetrics(g.getFont()).getHeight()), nWidth, nHeight, null);
}
nPos_x = 0;
nPos_y += (this.getFontMetrics(g.getFont()).getHeight());
nPos_y += 2 + nHeight;
}
} catch (java.net.MalformedURLException e){
System.err.println(e);
}
}
} else if(sSource.startsWith("BODY ")){
sSource = sSource.substring(new String("BODY ").length());

if(sSource.startsWith("BGCOLOR=")){
bRet = true;

sSource = sSource.substring(new String("BGCOLOR=").length());
sSource = sSource.substring(new String("'#").length());
int nRed = getHexNum(sSource.substring(0, 2));
int nBlue = getHexNum(sSource.substring(2, 4));
int nGreen = getHexNum(sSource.substring(4, 6));
oBackColor = new Color(nRed, nBlue, nGreen);
g.setColor(oBackColor);
g.fillRect(0,0,getSize().width,getSize().height);
g.setColor(oForeColor);
sSource = sSource.substring(new String("BGCOLOR=").length());
}
if(sSource.startsWith("BACKGROUND=")){
bRet = true;

String sImage = "";
int nHeight = 0;
int nWidth = 0;
StringTokenizer Start;

sSource = sSource.substring(new String("BACKGROUND=").length());
sSource = sSource.substring(new String("'").length());

Start = new StringTokenizer(sSource, "'");
if(Start.hasMoreTokens() == true){
sImage = Start.nextToken();
}

try {
Image Imag = this.getImage(new URL(this.getCodeBase() + sImage));
if(Imag != null){

MediaTracker Media = new MediaTracker(this);
Media.addImage(Imag, 0);
try {
Media.waitForID(0);
} catch (InterruptedException e) {
System.err.println(e);
}
for(int y = 0; y < (1 + getSize().height / Imag.getHeight(null)); y++){
for(int x = 0; x < (1 + getSize().width / Imag.getWidth(null)); x++){
g.drawImage(Imag, x * Imag.getWidth(null), y * Imag.getHeight(null), Imag.getWidth(null), Imag.getHeight(null), null); // Many
}
}
}
} catch (java.net.MalformedURLException e){
System.err.println(e);
}
sSource = sSource.substring(new String("BACKGROUND=").length());
}
} else if(sSource.startsWith("HR ")){
sSource = sSource.substring(new String("HR ").length());

if(sSource.startsWith("WIDTH=")){
bRet = true;

int nWert = 0;

sSource = sSource.substring(new String("WIDTH=").length());
sSource = sSource.substring(1, sSource.length() - 1);
if(sSource.endsWith("%")){
sSource = sSource.substring(0, sSource.length() - 1);
nWert = getSize().width / 100 * new Integer(sSource).intValue();
} else {
nWert = new Integer(sSource).intValue();
}

nPos_x = 0;
g.setColor(Color.lightGray);
g.drawLine(nStart_x + nPos_x, nStart_y + nPos_y,nWert, nStart_y + nPos_y);
g.setColor(oBackColor);
nPos_y += 1;
g.drawLine(nStart_x + nPos_x, nStart_y + nPos_y,nWert, nStart_y + nPos_y);
g.setColor(oForeColor);
nPos_y += 10;

}
} else if(sSource.compareTo("/TABLE") == 0){
bRet = true;
bTable = false;
} else if(sSource.startsWith("TABLE ")){
sSource = sSource.substring(new String("TABLE ").length());
if(sSource.startsWith("COLS=")){
bRet = true;
sSource = sSource.substring(new String("COLS=").length());
StringTokenizer Start = new StringTokenizer(sSource);
if(Start.hasMoreTokens() == true){
String sStri= Start.nextToken();
nTableCols = new Integer(sStri).intValue();
sSource = sSource.substring(sStri.length() + 1);
}
bTable = true;
}
if(sSource.startsWith("WIDTH=")){
bRet = true;

int nWert = 0;

sSource = sSource.substring(new String("WIDTH=").length());
sSource = sSource.substring(1, sSource.length() - 1);
if(sSource.endsWith("%")){
sSource = sSource.substring(0, sSource.length() - 1);
nWert = getSize().width / 100 * new Integer(sSource).intValue();
} else {
nWert = new Integer(sSource).intValue();
}
nTableWidth = nWert;
}
}

if(bRet == false){
int nAlt_x = nStart_x + nPos_x;
// plain text
String sStri = macheUmlaute(sSource);
int ntPos_y = 0;
g.drawString(sStri, nStart_x + nPos_x, nStart_y + nPos_y + ntPos_y);
nPos_x += (this.getFontMetrics(g.getFont()).stringWidth(sStri));

if(bUnderline==true){
g.drawLine(nStart_x + nPos_x, 2 + nStart_y + nPos_y + ntPos_y, nAlt_x, 2 + nStart_y + nPos_y + ntPos_y);
}
}
if(bRet == true){
int nWert = 0;
int nWert2 = 0;

if(bBold == true){
nWert |= Font.BOLD;
}
if(bItalic == true){
nWert |= Font.ITALIC;
}
switch(nSize){
case 8:
nWert2 = nSize + 2;
break;
case 10:
nWert2 = nSize + 2;
break;
case 12:
nWert2 = nSize + 2;
break;
case 14:
nWert2 = nSize + 2;
break;
case 18:
nWert2 = nSize + 2 * 2;
break;
case 24:
nWert2 = nSize + 4 * 2;
break;
case 36:
nWert2 = nSize + 6 * 2;
break;
}
oFont = new Font(sFontname, nWert, nWert2 + 2);
g.setFont(oFont);
g.setColor(oForeColor);
}
return(bRet);
}

public void saveOldValue(String sSource)
{
String sPush = "";

if(sSource.startsWith("FACE=")){
sPush = "FONT FACE='" + sFontname + "'";
oFontStack.push(sPush);
} else if(sSource.startsWith("COLOR=")){
int nWert1 = 0;
int nWert2 = 0;
int nWert3 = 0;
int nWert = 0;
String sStri = "";

nWert1 = oForeColor.getRed();
nWert1 <<= 16;

nWert2 = oForeColor.getGreen();
nWert2 <<= 8;

nWert3 = oForeColor.getBlue();
nWert = nWert1 + nWert2 + nWert3;

nWert += 0xF000000; // damit immer 6-stellig

sStri = new Integer(nWert).toHexString(nWert);
sStri = sStri.substring(1);

sPush = "FONT COLOR='#" + sStri + "'";
oFontStack.push(sPush);
} else if(sSource.startsWith("SIZE=")){
sPush = "FONT SIZE=" + nSize;
oFontStack.push(sPush);
}
}

public int getHexNum(String sNumber)
{
int nRet = 0;

for(int i = 0; i< sNumber.length(); i++){
int nWert = 0;
int nWert2 = 0;

switch(sNumber.charAt(i)){
case '0':
nWert = 0;
break;
case '1':
nWert = 1;
break;
case '2':
nWert = 2;
break;
case '3':
nWert = 3;
break;
case '4':
nWert = 4;
break;
case '5':
nWert = 5;
break;
case '6':
nWert = 6;
break;
case '7':
nWert = 7;
break;
case '8':
nWert = 8;
break;
case '9':
nWert = 9;
break;
case 'A':
case 'a':
nWert = 10;
break;
case 'B':
case 'b':
nWert = 11;
break;
case 'C':
case 'c':
nWert = 12;
break;
case 'D':
case 'd':
nWert = 13;
break;
case 'E':
case 'e':
nWert = 14;
break;
case 'F':
case 'f':
nWert = 15;
break;

}
nWert2 = 1;
for(int i2 = 0; i2 < (sNumber.length() - i - 1); i2++){
nWert2 *= 16;
}
nRet += nWert2 * nWert;
}
return(nRet);
}

public Html() {
this.setBackground(SystemColor.desktop);
this.setFont(new java.awt.Font("Dialog", 1, 12));
}
}