import java.awt.*;
import java.awt.image.*;
import java.applet.*;
import java.util.*;
import java.net.*;
import java.io.*;
public class baseticker extends Applet implements Runnable{
			int wordsSpace=5,lettersSpace=2,msgIndex;
			byte[] lettersArray,messageImageArray;
			int lettersImageHeight,lettersImageWidth;
      Thread engineThread=null;
      Image offscreenImage=null;
			Hashtable lettersTable = null,messagesList=null;
			Vector properties=null;
      int numberOfMessages,waitTime;
      String target;
      URL href;
      Integer currentMessageWidh;
      Color fgColor,bgColor;
      AudioClip sound;
      IndexColorModel currentColorModel;
//________________________________________________________________________

       public Color String2Color(String strColor){
      	try{
      		return new Color(Integer.parseInt(strColor,16));
      	}catch (NumberFormatException e){
      		System.err.println("String2Color:Invalid color code:"+strColor);
      		System.err.println(e);
      		return null;
      	}
      }//end String2Color
      	
//________________________________________________________________________

       public URL String2URL(String strURL){
      	try{
      		return new URL(strURL);	
      	}catch(MalformedURLException e){}
      	try{
      		return new URL(getDocumentBase(),strURL);
      	}catch(MalformedURLException e){
      	System.err.println("String2URL: invalid url string:"+strURL);
      	System.err.println(e);
       	return null;
     		}
      }//end String2URL
      	
//________________________________________________________________________

       public Color getParameter(String name,Color defaultColor){
      	
      	Color newColor=String2Color(getParameter(name));
      	return (newColor==null?defaultColor:newColor);	
      }//end Color getParameter
//________________________________________________________________________

      
      public URL getParameter(String name,URL defaultURL){
      	
      	URL newURL=String2URL(getParameter(name));
      	if(newURL==null){
      		System.err.println("Invalid value for parameter "+name);
      		return defaultURL;
      	}else
      		return newURL;	
      }//end URL getParameter
      
//________________________________________________________________________


      protected void createLettersArray()
      	throws IOException{
      	URL url=null;
      	url=getParameter("fontImageSRC",url);
      	if (url==null){
      		IOException e=new IOException("invalid value for parameter lettersImageSRC");
      		throw e;
      	}
      	MediaTracker  tracker;	
      	Image img=getImage(url);
      	tracker  =  new  MediaTracker(this);
        tracker.addImage(img,  0);
        try  {
            tracker.waitForID(0);
        } catch  (InterruptedException  e)  {
        	System.err.println(e);
            return;
        }      	
        lettersImageHeight=img.getHeight(this);
      	lettersImageWidth=img.getWidth(this);
        int[]  pixels  =  new  int[lettersImageWidth  *  lettersImageHeight];
        PixelGrabber  pg  =  
                new  PixelGrabber(img,  0,  0,  lettersImageWidth,  lettersImageWidth,  pixels,  0,  lettersImageWidth);
        try  {
                pg.grabPixels();
        }  catch  (InterruptedException  e)  {
                System.err.println("interrupted  waiting  for  pixels!");
                return;
        }
        if  ((pg.status()  &  ImageObserver.ABORT)  !=  0)  {
              System.err.println("image  fetch  aborted  or  errored");
              return;
        }
	      Color fontImageFgColor=getParameter("fontImageFgColor",Color.black);
	      Color fontImageBgColor=getParameter("fontImageBgColor",Color.white);
        lettersArray=new byte[pixels.length];
        for(int i=0;i<pixels.length;i++){
        	if(pixels[i]==fontImageFgColor.getRGB())	
        		lettersArray[i]=(byte)1;
        	else
        		lettersArray[i]=(byte)0;
        }
        
      }//end createLettersArray
      	
//________________________________________________________________________
      	
      protected void createLettersTable() 
      	throws IOException{
      	URL url=null;
      	url=getParameter("lettersTextSRC",url);
      	if (url==null){
      		IOException e=new IOException("invalid value for parameter lettersImageSRC");
      		throw e;
      	}
      	
				URLConnection conn = null;
				//DataInputStream data = null;
				StreamTokenizer tokens;
		    conn = url.openConnection();
		    conn.connect();
		    //data = new DataInputStream(new BufferedInputStream(conn.getInputStream()));
				tokens=new StreamTokenizer(new BufferedInputStream(conn.getInputStream()));
				tokens.ordinaryChar(45);
				tokens.ordinaryChar(46);
				tokens.wordChars(33, 47);
				tokens.wordChars(58, 127);
				tokens.eolIsSignificant(true);
				int currentToken=0;
				
				String letterName;
				int[] letterLocation;
				lettersTable=new Hashtable();
				Vector lineVector=new Vector();
				while(currentToken!=StreamTokenizer.TT_EOF){
					letterLocation=new int[2];
					letterLocation[0]=-1;
					letterLocation[1]=-1;
					letterName=null;
					lineVector.removeAllElements();
					while(true){
						currentToken=tokens.nextToken();
						if((currentToken==StreamTokenizer.TT_EOF)||(currentToken==StreamTokenizer.TT_EOL))
							break;
						if(currentToken==StreamTokenizer.TT_WORD)
							lineVector.addElement(tokens.sval);
						try{
							if(currentToken==StreamTokenizer.TT_NUMBER)
								lineVector.addElement(new Integer((int)tokens.nval));
						}catch(NumberFormatException e){}
				
					}
					Object obj;
					if((obj=lineVector.elementAt(0))!=null){
						letterName=obj.toString();
						if(letterName.length()==1)
								letterName=String.valueOf((int)(letterName.charAt(0)));
					}
					obj=lineVector.elementAt(1);
					if(obj!=null)
						letterLocation[0]=((Integer)obj).intValue();
					
					if((obj=lineVector.elementAt(2))!=null)
						letterLocation[1]=((Integer)obj).intValue();
						
					if((letterName!=null)&&(letterLocation[0]!=-1)&&(letterLocation[1]!=-1))
						lettersTable.put(letterName,letterLocation);
					
				}
				
	
      }//end createLettersTable
      	
//________________________________________________________________________

       	
      protected void createProperies() {
	      	properties=new Vector();
	      	properties.addElement("au");
	      	properties.addElement("FgColor");
	      	properties.addElement("BgColor");
	      	properties.addElement("Href");
	      	properties.addElement("FontSize");
      }//end createProperies
      protected void createMessagesList() {
				//DataInputStream data = null;
				messagesList=new Hashtable();
      	numberOfMessages=1;
      	//input messages from parameters
      	String par;
      	for(int i=1;(par=getParameter("msg"+i+"text"))!=null;i++){
      		messagesList.put("msg"+i+"text",par);

//      		if((par=getParameter("msg"+i+"au"))!=null)
//      			messagesList.put("msg"+i+"au",par);
//      		if((par=getParameter("msg"+i+"FgColor"))!=null)
//      			messagesList.put("msg"+i+"FgColor",par);
//      		if((par=getParameter("msg"+i+"BgColor"))!=null)
//      			messagesList.put("msg"+i+"BgColor",par);
//      		if((par=getParameter("msg"+i+"Href"))!=null)
//      			messagesList.put("msg"+i+"Href",par);
//      		if((par=getParameter("msg"+i+"FontSize"))!=null)
//      			messagesList.put("msg"+i+"FontSize",par);
						for(int j=0;j<properties.size();j++){
							String prop=(String)properties.elementAt(j);
		      		if((par=getParameter("msg"+i+prop))!=null)
		      			messagesList.put("msg"+i+(String)properties.elementAt(j),par);
						}
      		//System.out.println("messagesList="+messagesList);
       		numberOfMessages++;
     	}
      	//System.out.println("numberOfMessages="+numberOfMessages);
     		//input messages from file
     		try{
	      	URL url=null;
	      	url=getParameter("messagesTextSRC",url);
	      	if (url==null){
	      		IOException e=new IOException("invalid value for parameter lettersImageSRC");
	      		throw e;
	      	}
					URLConnection conn = null;
					StreamTokenizer tokens;
			    conn = url.openConnection();
			    conn.connect();
			    
					tokens=new StreamTokenizer(new BufferedInputStream(conn.getInputStream()));
					
					int currentToken=0;
	     		String temp;
					String messageText="",line="";
					while(currentToken!=StreamTokenizer.TT_EOF){
						tokens.resetSyntax();
						tokens.wordChars(32, 127);
						tokens.wordChars(150, 255);
						tokens.whitespaceChars(0, 31);
						currentToken=tokens.nextToken();
						line=tokens.sval;
						if(line==null)
							continue;
						
	
						//System.out.println("line="+line);
						StringBuffer buf=new StringBuffer();
						int i=0;
						for(i=0;buf.length()<4;i++){
							if(i>=line.length())
								break;
							if((int)line.charAt(i)!=32)
								buf.append(line.charAt(i));
						}
						
							
							//System.out.println("buf="+buf);
							
							if(buf.toString().equalsIgnoreCase("[msg")){
								if(messageText.length()!=0)
									messagesList.put("msg"+(numberOfMessages-1)+"text",messageText);
								messageText="";
								
								for(buf=new StringBuffer();i<line.length();i++){
									if((int)line.charAt(i)==32){
										if(i>0)
											if((line.charAt(i-1)=='=')||(line.charAt(i-1)==' '))
												continue;
										if(i<line.length())
											if((line.charAt(i+1)=='=')||(line.charAt(i+1)==' '))
												continue;
									}
									buf.append(line.charAt(i));
								}
								//System.out.println("buf="+buf);
								StringTokenizer st=new StringTokenizer(buf.toString());
								while(st.hasMoreTokens()){
									String lineToken=st.nextToken();
									int eq=lineToken.indexOf('=');
									if(eq==-1)
										continue;
									
									String left=lineToken.substring(0,eq);
									String right=lineToken.substring(eq+1);
									if((right!=null)&&(left!=null))
										messagesList.put("msg"+numberOfMessages+left,right);
	//								//System.out.println("left="+left+" right="+right);
								}
									numberOfMessages++;
									//System.out.println("numberOfMessages="+numberOfMessages);

							}else{
								messageText=messageText+" "+line;
								//System.out.println("messageText="+messageText);
							}//end else
					}
								messageText=messageText;
								messagesList.put("msg"+(numberOfMessages-1)+"text",messageText);
								numberOfMessages--;

     			//data.close();
								//System.out.println("fuck");
     		}catch(IOException e){
     			System.err.println(e);
     		}
      }//createMessagesList 
      	
//________________________________________________________________________

 			protected int getLetterWidth(String letterCode){
 				int letter=0;
				try{
					letter=Integer.parseInt(letterCode);
				}catch(NumberFormatException e){}
				
				if(letter>=1488){
					letter-=1264;
					letterCode=String.valueOf(letter);
				}
				if(letterCode.equals("32"))
					return wordsSpace;
				int[] letterProps=(int[])lettersTable.get(letterCode);
				if(letterProps==null)
					return -1;
				else
					return letterProps[1]; 		
			}

//________________________________________________________________________

 
			protected int getLetterX(String letterCode){
 				int letter=0;
				try{
					letter=Integer.parseInt(letterCode);
				}catch(NumberFormatException e){}
				
				if(letter>=1488){
					letter-=1264;
					letterCode=String.valueOf(letter);
				}
				int[] letterProps=(int[])lettersTable.get(letterCode);
				if(letterProps==null)
					return -1;
				else
					return letterProps[0]; 		
			}

//________________________________________________________________________

 
			protected void createMessageImageArray(){
				String currentMessage=(String)messagesList.get("msg"+msgIndex+"text");
				
				currentMessageWidh=(Integer)messagesList.get("messageWidth"+msgIndex);
				if(currentMessageWidh==null){
					int sum=0;
					for(int i=0;i<currentMessage.length();i++){
						String currentLetter=String.valueOf((int)currentMessage.charAt(i));
						//System.out.println("getMessageImageArray currentMessage.charAt(i)="+currentMessage.charAt(i));
						if(currentMessage.charAt(i)=='$'){
							if(i+1<currentMessage.length()){
								if(currentMessage.charAt(i+1)=='$'){
									StringBuffer buf=new StringBuffer();
									int j;
									for(j=i+2;j<currentMessage.length();j++){
										if(currentMessage.charAt(j)==' ')
											break;
										buf.append(currentMessage.charAt(j));
									}
									//System.out.println("getMessageImageArray buf="+buf);
									if(lettersTable.get(buf.toString())!=null){
										i=j;
										currentLetter=buf.toString();
									}
										
								}
							}
						}//end if(currentMessage.charAt(i)=='$')
						sum+=getLetterWidth(currentLetter);
						if((i<=0)||(currentLetter=="32"))
							continue;
						if(currentMessage.charAt(i-1)==' ')
							continue;
						sum+=lettersSpace;
					}//end for(int i=0;...
					currentMessageWidh=new Integer(sum);
					lettersTable.put("message"+msgIndex,currentMessageWidh);
				}//end if
				//System.out.println("getMessageImageArray currentMessageWidh="+currentMessageWidh);	
				
				//  \\\\__________|\
				//  -|||__________   > create the array
				//  ////          |/

//				int x,y,currentMessageFontSize=1;
//				try{
//					currentMessageFontSize=Integer.parseInt((String)(messagesList.get("msg"+msgIndex+"fontSize")));
//				}catch(NumberFormatException e){}
//				x=(offscreenImage.getWidth(this)-messageImage.getWidth(this)*currentMessageFontSize)/2;
//				y=(offscreenImage.getHeight(this)-messageImage.getHeight(this)*currentMessageFontSize)/2;

				messageImageArray=new byte[currentMessageWidh.intValue()*lettersImageHeight];
				for(int i=0;i<messageImageArray.length;i++)
					messageImageArray[i]=(byte)0;
				int xOffset=0;

				for(int i=0;i<currentMessage.length();i++){
					String currentLetter=String.valueOf((int)currentMessage.charAt(i));
					//System.out.println("getMessageImageArray currentMessage.charAt(i)="+currentMessage.charAt(i)+" currentLetter="+currentLetter);	
					if(currentMessage.charAt(i)==' '){
						xOffset+=wordsSpace;
						continue;
					}
					if(currentMessage.charAt(i)=='$'){
							if(i+1<currentMessage.length()){
								if(currentMessage.charAt(i+1)=='$'){
									StringBuffer buf=new StringBuffer();
									int j;
									for(j=i+2;j<currentMessage.length();j++){
										if(currentMessage.charAt(j)==' ')
											break;
										buf.append(currentMessage.charAt(j));
									}
									//System.out.println("getMessageImageArray buf="+buf);
									if(lettersTable.get(buf.toString())!=null){
										i=j-1;
										currentLetter=buf.toString();
									}	
								}
							}
						}//end if(currentMessage.charAt(i)=='$')

					int letterWidth=getLetterWidth(currentLetter);
					int letterX=getLetterX(currentLetter);
					
					if((letterWidth==-1)||(letterX==-1))
						continue;
					//System.out.println("getMessageImageArray currentLetter="+currentLetter+" letterWidth="+letterWidth+" letterX="+letterX+" lettersImageHeight="+lettersImageHeight);	
					
					for(int lineIndex=0;lineIndex<lettersImageHeight;lineIndex++){
						for(int colIndex=0;colIndex<letterWidth;colIndex++){
							//System.out.println("getMessageImageArray lineIndex="+lineIndex+" messageImageArray.length="+messageImageArray.length+" xOffset="+xOffset+" colIndex="+colIndex);
							messageImageArray[lineIndex*currentMessageWidh.intValue()+xOffset+colIndex]=lettersArray[lineIndex*lettersImageWidth+letterX+colIndex];
						}//end for(int colIndex=0;...
					}//end for(int lineIndex=0;...
					xOffset+=letterWidth;
						if(currentMessage.charAt(i)!=' ')
							if(i+1<currentMessage.length())
								if(currentMessage.charAt(i+1)!=' ')	
									xOffset+=lettersSpace;
					
					//System.out.println("getMessageImageArray xOffset="+xOffset);
				}//end for(int i=0;...
			}//end createMessageImageArray


//________________________________________________________________________


 			protected synchronized void showMessage(){
				
				//  \\\\__________|\
				//  -|||__________   > create the image
				//  ////          |/
				
        Color colorArray[] = new Color[2];//{backgroundColor, foregroundColor};
 				String s=(String)messagesList.get("msg"+msgIndex+"BgColor");
        if(s!=null)
        	colorArray[0]=(colorArray[0]=String2Color(s));
        else
        	colorArray[0]=bgColor;
        	
        s=(String)messagesList.get("msg"+msgIndex+"FgColor");
        if(s!=null)
        	colorArray[1]=(colorArray[1]=String2Color(s));
        else
        	colorArray[1]=fgColor;
        	
        byte reds[]   = new byte[colorArray.length];
        byte greens[] = new byte[colorArray.length];
        byte blues[]  = new byte[colorArray.length];
        for (int i=0;i<colorArray.length;i++) {
            reds[i]   = (byte)colorArray[i].getRed();
            greens[i] = (byte)colorArray[i].getGreen();
            blues[i]  = (byte)colorArray[i].getBlue();
        }				
        
        
//        byte[] cmap={(byte)backgroundColor.getRed(),(byte)backgroundColor.getGreen(),(byte)backgroundColor.getBlue(),(byte)foregroundColor.getRed(),(byte)foregroundColor.getGreen(),(byte)foregroundColor.getBlue()};
//				
//				IndexColorModel cm=new IndexColorModel(8, 2,cmap, 0);
//				offscreenImage  =  createImage(new MemoryImageSource(currentMessageWidh.intValue(), lettersImageHeight, cm, cmap, 0, currentMessageWidh.intValue()));
//				s=(String)messagesList.get("msg"+msgIndex+"fontSize");
//				if(s)
				Image messageImage=createImage(new MemoryImageSource (currentMessageWidh.intValue(), lettersImageHeight,new IndexColorModel (8, colorArray.length, reds, greens, blues),messageImageArray, 0, currentMessageWidh.intValue()));
				int x,y,currentMessageFontSize=1;
				try{
					currentMessageFontSize=Integer.parseInt((String)(messagesList.get("msg"+msgIndex+"fontSize")));
				}catch(NumberFormatException e){}
				x=(offscreenImage.getWidth(this)-messageImage.getWidth(this)*currentMessageFontSize)/2;
				y=(offscreenImage.getHeight(this)-messageImage.getHeight(this)*currentMessageFontSize)/2;
				Graphics offscreenGraphics=offscreenImage.getGraphics();
				offscreenGraphics.setColor(colorArray[0]);
				offscreenGraphics.fillRect(0,0,offscreenImage.getWidth(this),offscreenImage.getHeight(this));
				offscreenGraphics.drawImage(messageImage,x,y,messageImage.getWidth(this)*currentMessageFontSize,messageImage.getHeight(this)*currentMessageFontSize,this);
				
				repaint();
                 try{
                     engineThread.sleep(waitTime);
                 } catch (InterruptedException e){}
			}//end getMessageImageArray
      	
//________________________________________________________________________

       public void init(){
	      try{
	      	
					createLettersArray();
					
					createLettersTable();
					createProperies();
					createMessagesList();
//					System.out.println(messagesList);
	      fgColor=getParameter("fgColor",Color.black);
	      bgColor=getParameter("bgColor",Color.white);
	      offscreenImage=createImage(size().width,size().height);
	      target=getParameter("waitTime");
	      waitTime=0;
	      if(target==null){
	      	try{
	      		waitTime=Integer.parseInt(target);
	      	}catch(NumberFormatException e){}
	      }
	      if(waitTime==0)
	      	waitTime=2500;
	      	
	      href=null;
	      href=getParameter("sound",href);
	      if(href!=null)
	      	sound=getAudioClip(href);

	      href=null;
	      href=getParameter("href",href);
//	      href=getParameter("href",getDocumentBase());
//	      if(href==getDocumentBase())
//	      	href==null;
	      target=getParameter("target");
	      if(target==null)
	      	target="_parent";
	      	
	      
		    }catch(Exception e){
		    	System.err.println(e);
		    	}
      }
      
//________________________________________________________________________

       public void start(){
             if (engineThread==null){
               engineThread=new Thread(this);
               engineThread.start();
             }
      }//end start

//________________________________________________________________________

       public void stop(){
            engineThread.stop();
            engineThread=null;
      }//end stop

//________________________________________________________________________

 
      public void run(){
      			msgIndex=0;
            while (true) {
            	msgIndex++;
            	if(msgIndex>numberOfMessages)
            		msgIndex=1;
            	createMessageImageArray();
            	showMessage();
            }
      }//end run

//________________________________________________________________________

       public void paint(Graphics g){
      	if (offscreenImage!=null)
      		g.drawImage(offscreenImage,0,0,this);

    }//end paint
    	
//________________________________________________________________________

 	public void update(Graphics g){
		paint(g);
	}//end update

//________________________________________________________________________

 

	public boolean mouseMove(Event evt, int x, int y)
	{
		String msg=(String)(messagesList.get("msg"+msgIndex+"href"));
		if((msg==null)&&(href!=null))
			msg=href.toString();
		if(msg!=null)
			showStatus(msg);
		return true;
	}
	
//________________________________________________________________________



	public boolean mouseDown(Event evt, int x, int y)
	{
		
		String s=(String)(messagesList.get("msg"+msgIndex+"au"));
		URL url;
			System.out.println("s="+s);
		if(s!=null){

			url=String2URL(s);
			if(url!=null)
				play(url);
			else
				sound.play();
		}else
			sound.play();

		url=null;
		s=(String)(messagesList.get("msg"+msgIndex+"href"));
		
		if(s!=null){
			url=String2URL(s);
		}
			
		if(url==null)
			url=href;
		if(url!=null){
			if(url.getProtocol().equalsIgnoreCase("mailto"))
				getAppletContext().showDocument(url,"_self");
			else
				getAppletContext().showDocument(url,target);
			return true;
		}else
			return false;
			
	}

//	public synchronized Image getOffscreenImage()
//	{
//		return this.offscreenImage;
//	}
//
//	public synchronized void setOffscreenImage(Image offscreenImage)
//	{
//		this.offscreenImage = offscreenImage;
//	}
}//end baseticker
	
	
	
public class fadeticker extends baseticker implements Runnable{
	protected int calculateFade(int bg,int fg,float trans){
		return (int)(bg+(fg-bg)*trans);	
	}//end calculateFade
	protected void showMessage(){
				
				//  \\\\__________|\
				//  -|||__________   > create the image
				//  ////          |/
				
        Color colorArray[] = new Color[2];//{backgroundColor, foregroundColor};
 				String s=(String)messagesList.get("msg"+msgIndex+"BgColor");
        if(s!=null)
        	colorArray[0]=String2Color(s);
        else
        	colorArray[0]=bgColor;
        	
        s=(String)messagesList.get("msg"+msgIndex+"FgColor");
        if(s!=null)
        	colorArray[1]=(colorArray[1]=String2Color(s));
        else
        	colorArray[1]=fgColor;
        	
        byte reds[]   = new byte[colorArray.length];
        byte greens[] = new byte[colorArray.length];
        byte blues[]  = new byte[colorArray.length];
        for (int i=0;i<colorArray.length;i++) {
            reds[i]   = (byte)colorArray[i].getRed();
            greens[i] = (byte)colorArray[i].getGreen();
            blues[i]  = (byte)colorArray[i].getBlue();
        }				
        
        
//        byte[] cmap={(byte)backgroundColor.getRed(),(byte)backgroundColor.getGreen(),(byte)backgroundColor.getBlue(),(byte)foregroundColor.getRed(),(byte)foregroundColor.getGreen(),(byte)foregroundColor.getBlue()};
//				
//				IndexColorModel cm=new IndexColorModel(8, 2,cmap, 0);
//				offscreenImage  =  createImage(new MemoryImageSource(currentMessageWidh.intValue(), lettersImageHeight, cm, cmap, 0, currentMessageWidh.intValue()));
//				s=(String)messagesList.get("msg"+msgIndex+"fontSize");
//				if(s)
				boolean cell0bug=false;
				if(messageImageArray[0]==0){
					cell0bug=true;
					messageImageArray[0]=1;
				}
				
				Image messageImage=createImage(new MemoryImageSource (currentMessageWidh.intValue(), lettersImageHeight,new IndexColorModel (8, colorArray.length, reds, greens, blues,1),messageImageArray, 0, currentMessageWidh.intValue()));
				int x,y,w,h,currentMessageFontSize=1;
				try{
					currentMessageFontSize=Integer.parseInt((String)(messagesList.get("msg"+msgIndex+"fontSize")));
				}catch(NumberFormatException e){}
				w=messageImage.getWidth(this)*currentMessageFontSize;
				h=messageImage.getHeight(this)*currentMessageFontSize;
				x=(offscreenImage.getWidth(this)-w)/2;
				y=(offscreenImage.getHeight(this)-h)/2;
				
				Graphics offscreenGraphics=offscreenImage.getGraphics();
					offscreenGraphics.setColor(colorArray[0]);
					offscreenGraphics.fillRect(0,0,offscreenImage.getWidth(this),offscreenImage.getHeight(this));
				
				for(int i=0;i<=100;i++){
					try{
	          engineThread.sleep(5);
	        } catch (InterruptedException e){}
					
					offscreenGraphics.setColor(new Color(calculateFade(colorArray[0].getRed(),colorArray[1].getRed(),((float)i/100)),calculateFade(colorArray[0].getGreen(),colorArray[1].getGreen(),((float)i/100)),calculateFade(colorArray[0].getBlue(),colorArray[1].getBlue(),((float)i/100))));
					offscreenGraphics.fillRect(x,y,w,h);
					offscreenGraphics.drawImage(messageImage,x,y,w,h,this);
					if(cell0bug){
						offscreenGraphics.setColor(colorArray[0]);
						offscreenGraphics.fillRect(x,y,currentMessageFontSize,currentMessageFontSize);
					}
					try{
	          engineThread.sleep(5);
	        } catch (InterruptedException e){}

					repaint();
				}
                 try{
                     engineThread.sleep(waitTime);
                 } catch (InterruptedException e){}
//					offscreenGraphics.setColor(colorArray[0]);
//					offscreenGraphics.fillRect(0,0,offscreenImage.getWidth(this),offscreenImage.getHeight(this));
				for(int i=100;i>=0;i--){
					try{
	          engineThread.sleep(5);
	        } catch (InterruptedException e){}

					
					offscreenGraphics.setColor(new Color(calculateFade(colorArray[0].getRed(),colorArray[1].getRed(),((float)i/100)),calculateFade(colorArray[0].getGreen(),colorArray[1].getGreen(),((float)i/100)),calculateFade(colorArray[0].getBlue(),colorArray[1].getBlue(),((float)i/100))));
					offscreenGraphics.fillRect(x,y,w,h);
					offscreenGraphics.drawImage(messageImage,x,y,w,h,this);
					if(cell0bug){
						offscreenGraphics.setColor(colorArray[0]);
						offscreenGraphics.fillRect(x,y,currentMessageFontSize,currentMessageFontSize);
					}
					try{
	          engineThread.sleep(5);
	        } catch (InterruptedException e){}

					repaint();
				}
			}//end getMessageImageArray


}//end fadeticker
	
	
	
	
public class typeTicker extends baseticker implements Runnable{
	AudioClip typeSound=null;

	public void init()
	{
		super.init();
		try{
			typeSound=getAudioClip(new URL(getDocumentBase(),"msgtype.au"));
		}catch(MalformedURLException e){}
		System.out.println(messagesList);
	}
 			protected synchronized void showMessage(){
 				
				String currentMessage=(String)messagesList.get("msg"+msgIndex+"text");
 				Vector words=new Vector();
					int sum=0;
					for(int i=0;i<currentMessage.length();i++){
						words.addElement(new Integer(sum));
						String currentLetter=String.valueOf((int)currentMessage.charAt(i));
						//System.out.println("getMessageImageArray currentMessage.charAt(i)="+currentMessage.charAt(i));
						if(currentMessage.charAt(i)=='$'){
							if(i+1<currentMessage.length()){
								if(currentMessage.charAt(i+1)=='$'){
									StringBuffer buf=new StringBuffer();
									int j;
									for(j=i+2;j<currentMessage.length();j++){
										if(currentMessage.charAt(j)==' ')
											break;
										buf.append(currentMessage.charAt(j));
									}
									//System.out.println("getMessageImageArray buf="+buf);
									if(lettersTable.get(buf.toString())!=null){
										i=j;
										currentLetter=buf.toString();
									}
										
								}
							}
						}//end if(currentMessage.charAt(i)=='$')
						sum+=getLetterWidth(currentLetter);
						if((i<=0)||(currentLetter.equals("32")))
							continue;
						
						if(currentMessage.charAt(i-1)==' ')
							continue;
						sum+=lettersSpace;
					}//end for(int i=0;...
//					System.out.println(words);
				//  \\\\__________|\
				//  -|||__________   > create the image
				//  ////          |/
				
        Color colorArray[] = new Color[2];//{backgroundColor, foregroundColor};
 				String s=(String)messagesList.get("msg"+msgIndex+"BgColor");
        if(s!=null)
        	colorArray[0]=(colorArray[0]=String2Color(s));
        else
        	colorArray[0]=bgColor;
        	
        s=(String)messagesList.get("msg"+msgIndex+"FgColor");
        if(s!=null)
        	colorArray[1]=(colorArray[1]=String2Color(s));
        else
        	colorArray[1]=fgColor;
        	
        byte reds[]   = new byte[colorArray.length];
        byte greens[] = new byte[colorArray.length];
        byte blues[]  = new byte[colorArray.length];
        for (int i=0;i<colorArray.length;i++) {
            reds[i]   = (byte)colorArray[i].getRed();
            greens[i] = (byte)colorArray[i].getGreen();
            blues[i]  = (byte)colorArray[i].getBlue();
        }				
        
        
//        byte[] cmap={(byte)backgroundColor.getRed(),(byte)backgroundColor.getGreen(),(byte)backgroundColor.getBlue(),(byte)foregroundColor.getRed(),(byte)foregroundColor.getGreen(),(byte)foregroundColor.getBlue()};
//				
//				IndexColorModel cm=new IndexColorModel(8, 2,cmap, 0);
//				offscreenImage  =  createImage(new MemoryImageSource(currentMessageWidh.intValue(), lettersImageHeight, cm, cmap, 0, currentMessageWidh.intValue()));
//				s=(String)messagesList.get("msg"+msgIndex+"fontSize");
//				if(s)
				Image messageImage=createImage(new MemoryImageSource (currentMessageWidh.intValue(), lettersImageHeight,new IndexColorModel (8, colorArray.length, reds, greens, blues),messageImageArray, 0, currentMessageWidh.intValue()));
				int x,y,w,currentMessageFontSize=1;
				try{
					currentMessageFontSize=Integer.parseInt((String)(messagesList.get("msg"+msgIndex+"fontSize")));
				}catch(NumberFormatException e){}
				x=(offscreenImage.getWidth(this)-messageImage.getWidth(this)*currentMessageFontSize)/2;
				y=(offscreenImage.getHeight(this)-messageImage.getHeight(this)*currentMessageFontSize)/2;
				Graphics offscreenGraphics=offscreenImage.getGraphics();
				for(int i=words.size()-1;i>=0;i--){
					w=((Integer)words.elementAt(i)).intValue();
					offscreenGraphics.setColor(colorArray[0]);
					offscreenGraphics.fillRect(0,0,offscreenImage.getWidth(this),offscreenImage.getHeight(this));
					offscreenGraphics.drawImage(messageImage,x,y,messageImage.getWidth(this)*currentMessageFontSize,messageImage.getHeight(this)*currentMessageFontSize,this);
					offscreenGraphics.fillRect(x,y,w*currentMessageFontSize,offscreenImage.getHeight(this));
					if(typeSound!=null)
						typeSound.play();
					repaint();
//					System.out.println(w);
					
                 try{
                     engineThread.sleep(500);
                 } catch (InterruptedException e){}
				}
                 try{
                     engineThread.sleep(waitTime);
                 } catch (InterruptedException e){}
			}//end getMessageImageArray
}//end typeTicker
	
	
	
	
public class moveTicker extends baseticker implements Runnable{
	protected void createProperies() {
		super.createProperies();
		properties.addElement("comeDirection");	
		properties.addElement("goDirection");	
		
	}//end createProperies


 			protected synchronized void showMessage(){
				
				//  \\\\__________|\
				//  -|||__________   > create the image
				//  ////          |/
				
        Color colorArray[] = new Color[2];//{backgroundColor, foregroundColor};
 				String s=(String)messagesList.get("msg"+msgIndex+"BgColor");
        if(s!=null)
        	colorArray[0]=(colorArray[0]=String2Color(s));
        else
        	colorArray[0]=bgColor;
        	
        s=(String)messagesList.get("msg"+msgIndex+"FgColor");
        if(s!=null)
        	colorArray[1]=(colorArray[1]=String2Color(s));
        else
        	colorArray[1]=fgColor;
        	
        byte reds[]   = new byte[colorArray.length];
        byte greens[] = new byte[colorArray.length];
        byte blues[]  = new byte[colorArray.length];
        for (int i=0;i<colorArray.length;i++) {
            reds[i]   = (byte)colorArray[i].getRed();
            greens[i] = (byte)colorArray[i].getGreen();
            blues[i]  = (byte)colorArray[i].getBlue();
        }				
        
        
				Image messageImage=createImage(new MemoryImageSource (currentMessageWidh.intValue(), lettersImageHeight,new IndexColorModel (8, colorArray.length, reds, greens, blues),messageImageArray, 0, currentMessageWidh.intValue()));
				int x,y,currentMessageFontSize=1;
				try{
					currentMessageFontSize=Integer.parseInt((String)(messagesList.get("msg"+msgIndex+"fontSize")));
				}catch(NumberFormatException e){}
				x=(offscreenImage.getWidth(this)-messageImage.getWidth(this)*currentMessageFontSize)/2;
				y=(offscreenImage.getHeight(this)-messageImage.getHeight(this)*currentMessageFontSize)/2;
				int startX,endX,startY,endY;
				String comeDirection=(String)messagesList.get("msg"+msgIndex+"comeDirection");
				String goDirection=(String)messagesList.get("msg"+msgIndex+"goDirection");
				
				switch(comeDirection){
					case: "up"
						startX=endX=0;
						startY=-messageImage.getHeight(this);
						endY=y;
						break;
					case: "down"
						startX=endX=0;
						startY=-messageImage.getHeight(this);
						endY=y;
						break;
					case: "left"
						break;
					case: "right"
						break;
				}	
				Graphics offscreenGraphics=offscreenImage.getGraphics();
				offscreenGraphics.setColor(colorArray[0]);
				offscreenGraphics.fillRect(0,0,offscreenImage.getWidth(this),offscreenImage.getHeight(this));
				offscreenGraphics.drawImage(messageImage,x,y,messageImage.getWidth(this)*currentMessageFontSize,messageImage.getHeight(this)*currentMessageFontSize,this);
				
				repaint();
                 try{
                     engineThread.sleep(waitTime);
                 } catch (InterruptedException e){}
			}//end showMessage

		
}//end 