//////////////////////////////////////////////////
//
//   Scrolling Message Pusher V2.6
//
//   Copyright 1997 - 2000 Kenny A. Chaffin
//
//   KAC Website Design - http://www.kacweb.com
//
//   Created 3/19/97 by Kenny A. Chaffin
//
//   Last Updated 4/30/00 by Kenny A. Chaffin
//
//   added browserreload parameter  to reload from server
//   default is false
//   changed to suspend and resume thread 
//   2.0 - added frame targeting
//   2.0 - added multiline driver files -- each item on a line.
//   2.01 - added console version printing on initialization
//   2.1 - added setUseCaches() disable
//   2.2 - 4/7/98 added selectable channel file name parameter.
//   2.6 - 4/8/98 added ability to switch channels within channel file.
//   2.6 - 4/30/00 released source code
//
/////////////////////////////////////////////////


// Standard Java Imports

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


public class Scrollpush extends java.applet.Applet implements Runnable {

  
   // ************** this MUST be set appropriately!  ****************
   
//    private String base = "file:///D|/java-mine/scrollpush/";
//    private String base = "http://100.100.100.120/kacweb/banner/";
//    private String base = "http://www.kacweb.com/adserver/banner/";
    private String base = "http://www.kacweb.com/jticker/";
	
  // *******************************************************************


  // set to true for debugging info to be printed on system console
  
    private boolean debug = false;
    private boolean allowchannelstring = false;

  // sponsor information
    
    private int channelboxcolor = 0xFF0000;     // color for offsetbox
    private String channelstring = "Channel";	//String to display in sponser area
    private int channelcolor = 0xFFFFFF; 	// color to display string in
    private int channelshadowcolor = 0x000000; 	// dropshadow color for above
//    private String sponserwhere = "http://www.kacweb.com";
     


    private URL clickDest;
    private String where, tempstring;
    private String channelfile;
    private String channel;
    private String channelfilename = "channels";
    private String originalchannelfile = "channels";
    private int numberofads, adnumber;
    private int messagewait = 5000;      // 5 seconds
    Rectangle r;
    String tok;
    StringTokenizer st;
    private String adstring;
    private String origadstring;
    private String textstring;
    private boolean autoreload = false; // to enable automatic reloading of channel
    private int reloadloops;		// number of loops before reload
    private int loops;			// loop counter
    private boolean mousein = false;
    private boolean horizontal = false;	// true if scrolling horizontally
    private boolean left = true;	// true if scrolling left	
    private boolean down = false;	// true if scrolling down - up is default	
    private boolean done = false;
    private boolean browserreload = false;  // reload channel on browser reload?
    URL url;
    private int horizpixshift = 4;
    private int vertpixshift = 1;
    Thread scrollingmessage;
    String s;				// the message
    int s_length;			// negative width in pixels of the message
    int s_width;            		// actual width of string
    int top;				// top of display when scrolling vertically
    int stringx;			// current x-position
    int stringy;			// current y-position
    int pixelshift;			// scrolling amount
    int textcolor = 0x000000;		// (integer) text color
    int highlighttextcolor; 		// color when mouse is over text
    boolean highlighttext = false;
    int backcolor;			// (integer) background color
    int bordercolor;			// color to use for border highlight
    int delay;				// scrolling speed
    int width, height;
    private int offsetright;    	// pixels to reserve on right
    int mousex, mousey;   		// where's the mouse?
    Image offScreenImage; 		// for double buffering to prevent flicker
    Graphics offScreen;
    String font_name;			// name of the font
    int font_size;			// font size (points)
    Font wordFont;
    FontMetrics wordMetrics;
    boolean getchannelflag = false;    	//flag for changing channels   
    boolean reload = false;            	// reload flag
    boolean suspended = true;		// if on this page...
    String targetframe;			// if user wants to target a frame
    StringBuffer textbuffer; 		// for reading in text to display


  public void init() 
    {
      String temp;


      System.out.println(getAppletInfo());	//print the info on console
      height = size().height;		//set the size
      width = size().width;
      
      try 
        {
	  offScreenImage = createImage (width, height);
	  offScreen = offScreenImage.getGraphics ();
	} 
      catch (Exception e) 
        {
  	  offScreen = null;
        }

     						// get the name and size of the font
     temp=getParameter("font");
     font_name= (temp==null) ? "TimesRoman" : temp;
     temp = getParameter("fontsize");
     font_size= (temp==null) ? 12 : Integer.parseInt( temp );

     						// initialise the font
     wordFont = new Font(font_name, Font.BOLD, font_size);
     if (wordFont == null)
       wordFont = getFont();
     wordMetrics = getFontMetrics (wordFont);

    
    						// get the sponsor box background color
    temp = getParameter("channelboxcolor");
    channelboxcolor= (temp==null) ? 0xff0000 : Integer.parseInt(temp, 16);
    						// get the sponser text color 
    temp = getParameter("channelcolor");
    channelcolor= (temp==null) ? 0xFFFFFF : Integer.parseInt(temp, 16);
    						// set drop shadow color
    temp = getParameter("channelshadowcolor");
    channelshadowcolor= (temp==null) ? 0x000000 : Integer.parseInt(temp, 16);
    					// get the color of the text and background
    temp = getParameter("highlighttextcolor");
    highlighttextcolor = (temp==null) ? textcolor : Integer.parseInt(temp, 16);
    highlighttext = (temp==null) ? false : true;       // set the highlight on or off
    temp = getParameter("backcolor");
    backcolor= (temp==null) ? 0xffffff : Integer.parseInt(temp, 16);
    temp = getParameter("bordercolor");
    bordercolor = (temp==null) ? 0xff0000 : Integer.parseInt(temp, 16);

    					// get the speed of the scrolling
    temp = getParameter("horizpixshift");
    horizpixshift = (temp==null) ? 4 : Integer.parseInt( temp );
    temp = getParameter("vertpixshift");
    vertpixshift = (temp==null) ? 1 : Integer.parseInt( temp );
    
    temp = getParameter("delay");
    delay= (temp==null) ? 100 : Integer.parseInt( temp );
    temp = getParameter("messagewait");
    messagewait = (temp==null) ? 5000 : Integer.parseInt( temp );
      // read the ad file and get the info to display
    temp = getParameter("reloadloops");
    reloadloops = (temp==null) ? 100 : Integer.parseInt( temp );
    autoreload = (temp==null) ? false : true;

// System.out.println(reloadloops + " , " + autoreload);

//    temp = getParameter("browserreload");
//    browserreload = (temp==null) ? false : true;
    temp = getParameter("browserreload");
    if (temp==null)
      {
        browserreload = false;
      }
    else
      {
        temp = temp.toLowerCase();
        browserreload = (temp.equals("true")) ? true : false;
      } 

    temp = getParameter("targetframe");
    targetframe = (temp==null) ? "_self" : temp;

    temp = getParameter("channelfilename");
    channelfilename = (temp==null) ? "channels" : temp;
    originalchannelfile = channelfilename;

    channel = getParameter("channel");	// get the channel parameter
    loadchannel(channel);
    scrollingmessage = new Thread(this); 	// start the thread
    scrollingmessage.start();	
    suspended = false;
   }


  public void setparams(String stext)
    {
       offsetright = wordMetrics.stringWidth(channelstring) + 6;  // Reserve Channel Name space on right
       s = (stext==null) ? "..." : stext;
       s_length = -wordMetrics.stringWidth(s);
       s_width = wordMetrics.stringWidth(s);
       
		// Set the initial coordinates
       if (!horizontal)
         {
	   stringx = ((width  - offsetright) - s_width)/2;
	   top = (height - (wordMetrics.getHeight()-wordMetrics.getLeading()))/2 + (wordMetrics.getHeight()-wordMetrics.getLeading()-wordMetrics.getDescent());		 
           if (down)
             stringy = -wordMetrics.getDescent(); 	//start at the top
           else
              stringy = height + (wordMetrics.getHeight()-wordMetrics.getLeading()-wordMetrics.getDescent()); 	//start at the bottom          
	 }
       else             //horizontal scrolling
	 {
           stringy = (height - (wordMetrics.getHeight()-wordMetrics.getLeading()))/2 + (wordMetrics.getHeight()-wordMetrics.getLeading()-wordMetrics.getDescent());
	   if (left)
	     {
   	       stringx = width - offsetright;
   	     }
   	   else                 //right shift
   	     {
   	       stringx = s_length;
   	     }
   	  }
      }


  public void start() 
     {
       if (suspended)
         {
           scrollingmessage.resume();
           suspended = false;
         }
       if (browserreload)
         {
           loadchannel(channel);			//reload from server if enabled
         }
     }
	
  public void stop() 
    {
      scrollingmessage.suspend();
      suspended = true;
    }


  public void run() 
    {
	  String temp;
 						// set priority low
      Thread.currentThread().setPriority(Thread.MIN_PRIORITY);	
      while(true) 
        {
          if (autoreload && (loops <= 0))
            {
              loadchannel(channel);
            }
          if (reload)
            {
              loops = reloadloops;
            }
          adstring = origadstring;
          st = new StringTokenizer(adstring,"|");
          tok = st.nextToken();				// get number of items	
          try
	    {
	       numberofads = Integer.parseInt(tok);
	    }
	  catch (NumberFormatException e)
	    {
	      System.out.println("Integer Param Error");
 	    }
 	  channelstring = st.nextToken();  			// Channel Name
	  reload = false;
 bigloop:  for (adnumber = 1; adnumber <= numberofads; adnumber++)
             {
                where = st.nextToken();    	// get the url
                tok = st.nextToken();		// get scroll direction
                if (tok.equals("left"))
                  {
                    horizontal = true;
                    left = true;
                    pixelshift = horizpixshift;
                  }
                else
                if (tok.equals("right"))
                  {
                    horizontal = true;
                    left = false;
                    pixelshift = horizpixshift;
                  }
                else
                if (tok.equals("down"))
                  {
                    horizontal = false;
                    down = true;
                    pixelshift = vertpixshift;
                  }
                else
                  {
                    horizontal = false;
                    down = false;
                    pixelshift = vertpixshift;
                  } 
                tok = st.nextToken();	   		// get color
                textcolor = Integer.parseInt(tok, 16);  // set it.
                tok = st.nextToken();      		// get the string to display
                textstring = tok;
                setparams(textstring);
                if (mousein)              	// change the status bar if needed
                  {
                    showStatus(where);                
                  }
                done = false;
                if (where.indexOf("#SW,") == 0)
		{
//                  System.out.println("found a auto switch channel link");
                  temp = where.substring(4);
//                  System.out.println(temp);
                  where = temp;        			// set the channel name
//                  System.out.println(where); 
                  loadchannel(where);			// load the new channel
		  done = true;
		}

                while (!done)
 	          {
 		    if (horizontal)
		      {
		        if (left)
		          {
		            stringx -= pixelshift;
	 	            if (stringx < s_length)
		              {
                                stringx = width - offsetright;  // put back for delay so we don't get a shift on mouse in/out
//	Don'w wait if horizontal    
                                 				// reset starting point                            
		                done = true;
		              }		
		          }  					// end of left shift
		        else                 			// right shift
		          {
		            stringx += pixelshift;
	 	            if (stringx > (width - offsetright))
		              {
                                stringx = s_length;     	// put back for delay so we don't get a shift on mouse in/out
                                 // reset starting point                            
		                done = true;
		              }				          
		          } 					// end of right shift
	                 }
	             else                 			// vertical scrolling
                       if (!down)         			// scrolling up - default
	                {
	                   stringy -= pixelshift;
	                   if (stringy < top)
                             {
                               stringy = top;     	// put back for delay so we don't get a shift on mouse in/out
		 	       try 
			         {
			           Thread.sleep(messagewait);
			         } 
			       catch (InterruptedException e) {}
                                   // reset starting point                            
    	                       stringy = height + (wordMetrics.getHeight()-wordMetrics.getLeading()-wordMetrics.getDescent());
    	                       done = true;
    	                       	//start at the bottom
	                     }
	                 }
                     else
	                {
	                   stringy += pixelshift;
	                   if (stringy > top)
                             {
                               stringy = top;     	// put back for delay so we don't get a shift on mouse in/out
		 	       try 
			         {
			           Thread.sleep(messagewait);
			         } 
			       catch (InterruptedException e) {}
                                   // reset starting point                            
    	                       stringy = -wordMetrics.getDescent();
    	                       done = true;
    	                       	//start at the top
	                     }
	                 }
            	     repaint ();
            	     if (reload) 
            	       break bigloop;
		     try 
		       {
		         Thread.sleep(delay);
		       } 
	             catch (InterruptedException e) {}
	           }
  	         }
  	      if (autoreload)
  	        {
  	          loops--;
  	        }
// System.out.println(loops);
	    }
	} 
	    

  public void update (Graphics g) 
    {
      paint(g);
    }

  public synchronized void paint(Graphics g) 
    {
      if (offScreen!=null) 
        {
	   paintApplet(offScreen);
	   g.drawImage(offScreenImage,0,0,this);
	} 
      else
	paintApplet(g);
    }
	
	
  public void paintApplet(Graphics g) 
    {				
      g.setFont(wordFont);			// set the font in the graphics context
      g.setColor(new Color(backcolor));		// fill area with the background color
      g.fillRect(0,0,width,height);
      if (mousein && highlighttext)		// draw the string in the correct color
        g.setColor(new Color(highlighttextcolor));
      else
        g.setColor(new Color(textcolor));
      g.drawString (s, stringx, stringy);
      g.setColor(new Color(channelboxcolor));		// paint sponsor/owner name
      g.fillRect(width-offsetright, 0, offsetright, height-1);	
      g.setColor(Color.black);
      g.drawLine(width-offsetright, 0, width-offsetright, height-1);	
      g.setColor(new Color(channelshadowcolor));
      g.drawString(channelstring, width-offsetright+3+1, stringy+1);     
      g.setColor(new Color(channelcolor));
      g.drawString(channelstring, width-offsetright+3, stringy);     

	if (mousein == true)
          {
           //put a border around it
            g.setColor(new Color(bordercolor));
            g.drawRect(0, 0, width-1, height-1);	
            g.drawRect(1, 1,width-3,height-3);
          }
        else
          {
            g.setColor(Color.black);
            g.drawRect(0, 0, width-1, height-1);	
          }

	}
	
   public String fetch(String address)
      {   
       if (!debug)
         {
          String temp = "";
          textbuffer = new StringBuffer();
          InputStream conn = null;
          DataInputStream data = null;
          try
            {
              url = new URL(address);
            }
          catch (MalformedURLException e)
            { System.out.println("Bad URL: " + address);
            };
          try
            {
//              url.setDefaultUseCaches(false);
              conn = url.openStream();
              data = new DataInputStream(new BufferedInputStream(conn));
//              data.setUseCaches(false);
//              temp = data.readLine();
              while ((temp = data.readLine()) != null)
                {
                  textbuffer.append(temp + "|");
                }
              temp = textbuffer.toString();
            }
          catch (IOException e)
            { System.out.println("IO Exception: " + address);
            };
          return temp;
        }
      else
        {
          return ("2|Test Channel|http://www.kacweb.com|vertical|FF0000|This is a Test String|http://www.kacweb.com|left|0000FF|KAC Website Design|");
        }
    }
 
  public boolean mouseUp(Event e, int x, int y)
    {

      String temp = "";
      
      if (e.shiftDown())               // switch back to original start channel file
        {
          channelfilename = originalchannelfile;
          getchannel();
        }
      else
      if (e.controlDown())
        {
          loadchannel(channel);		// reload current channel - i.e. update
        }
      else
      if (getchannelflag)
        {
          loadchannel(where);
        }
      else
      if (where.indexOf("#C,") == 0)
        {
//          System.out.println("found a channel link");
          temp = where.substring(3);
//          System.out.println(temp);
          where = temp;        			// set the channel name
//          System.out.println(where); 
          loadchannel(where);			// load the new channel
        }
      else
      if (where.indexOf("#CS,") == 0)
        {
//          System.out.println("found a Master channel link");
          temp = where.substring(4);
//          System.out.println(temp);
          where = temp;        			// set the channel name
//          System.out.println(where); 
          loadchannel(where);			// load a channel selection channel
          getchannelflag = true;		// set the flag
          channelfilename = where;              // set the new channel file name
        }
      else
        {
//      if (x >= width-offsetright)      	// in the sponsor area?
//        {
//          try
//            {
//              clickDest = new URL(sponserwhere);	    
//            }
//          catch(MalformedURLException mal)
//            { 
//              System.out.println("Malformed URL:");
//            }
//        }
//      else
//        {
          try
            {
              clickDest = new URL(where);	    
            }
          catch(MalformedURLException mal)
            { 
              System.out.println("Malformed URL:");
            }
//        }
        getAppletContext().showDocument(clickDest, targetframe);
      }
      return true;
    }

  public boolean mouseEnter(Event e, int x, int y)
    {
      mousein = true;
      repaint();  
//      if (x >= width-offsetright)      	// in the sponsor area?
//        showStatus(sponserwhere);
//      else
          showStatus(where);
      return(true);
    }
    
  public boolean mouseExit(Event e, int x, int y)
    {
	mousein = false;
	repaint();                     		//remove border
	showStatus("");
	return(true);
    }

//  public boolean mouseMove(Event e, int x, int y)
//    {
//      mousex = x;
//      return(true);
//    }


  public void standby()				// Print "standby" message
    {
      horizontal = false;			// set to vertical
      setparams("Standby...");			// set up string
      stringy = top;				// center it
      repaint();
    }


  public void loadchannel(String where)
    {
      standby();				// print "standby" while waiting
      channel = where;				// save current channel
      tempstring = base + where + ".txt";   	//make full url
      channelfile = tempstring;
      origadstring = fetch(channelfile);          	//save it to repeat
//      getchannelflag = false;		     	//reset the flag for normal 
      if (!where.equals(channelfilename))
        {
          getchannelflag = false;		//reset the flag for normal 
        } 
      reload = true;
      loops = reloadloops;			// reset the loops counter
    }


  public void getchannel()                    	// switch channels
    {
      loadchannel(channelfilename);
      getchannelflag = true;		    	// set the flag
    }
    
 // Return the information on the applet
 
 public String getAppletInfo() 
	  {
	    return "Scrollpush Applet V2.6 4/8/98 Copyright 1997-2000 KAC Website Design - http://www.kacweb.com";
	  } // end of getAppletInfo
}