/* Rewrite.java  */

/* 
 * Copyright (C) 1996-98 Mark Boyns <boyns@sdsu.edu>
 *
 * This file is part of Muffin.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
package org.doit.muffin.filter;

import org.doit.muffin.*;
import org.doit.html.*;

import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import java.io.BufferedReader;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.Enumeration;
import gnu.regexp.*;

public class Rewrite implements FilterFactory
{
    FilterManager manager;
    Prefs prefs;
    RewriteFrame frame = null;
    MessageArea messages = null;

    Vector rules = null;
    Vector rewrite = null;

    public Rewrite ()
    {
    }

    public void setManager (FilterManager manager)
    {
	this.manager = manager;
    }
    
    public void setPrefs (Prefs prefs)
    {
	this.prefs = prefs;
	boolean o = prefs.getOverride ();
	prefs.setOverride (false);
	String filename = prefs.getUserFile ("rewrite");
	prefs.putString ("Rewrite.rules", filename);
	prefs.putInteger ("Rewrite.historySize", 500);
	prefs.setOverride (o);
	messages = new MessageArea (prefs.getInteger ("Rewrite.historySize"));
	load ();
    }

    public Prefs getPrefs ()
    {
	return prefs;
    }

    public void viewPrefs ()
    {
	if (frame == null)
	{
	    frame = new RewriteFrame (prefs, this);
	}
	frame.setVisible (true);
    }
    
    public Filter createFilter ()
    {
	Filter f = new RewriteFilter (this);
	f.setPrefs (prefs);
	return f;
    }

    public void shutdown ()
    {
	if (frame != null)
	{
	    frame.dispose ();
	}
    }

    void save ()
    {
	manager.save (this);
    }

    String rewrite (String url)
    {
	RE re = null;
	REMatch match = null;
	Enumeration e = rules.elements ();

	int index = 0;
	while (match == null && e.hasMoreElements ())
	{
	    re = (RE) e.nextElement ();
	    match = re.getMatch (url);
	    index++;
	}
	    
	if (match != null)
	{
	    String s = (String) rewrite.elementAt (index - 1);
	    try
	    {
		String sub = match.substituteInto (s);
		process ("RULE #" + index + ": " + url + " -> " + sub + "\n");
		url = sub;
	    }
	    catch (REException ex)
	    {
		System.out.println ("rewrite: " + ex);
	    }
	}
	
	return url;
    }

    void load ()
    {
	String filename = prefs.getUserFile (prefs.getString ("Rewrite.rules"));
	try
	{
	    load (new FileReader (new File (filename)));
	}
	catch (Exception e)
	{
	}
    }

    void load (Reader reader)
    {
	rules = new Vector ();
	rewrite = new Vector ();
		
	try
	{
	    BufferedReader in = new BufferedReader (reader);
	    String s;
	    RE blank = new RE ("^[# \t\n]");
	    
	    while ((s = in.readLine ()) != null)
	    {
		if (blank.getMatch (s) != null)
		{
		    continue;
		}

		StringTokenizer st = new StringTokenizer (s, " \t");
		try
		{
		    rules.addElement (new RE (st.nextToken ()));
		    rewrite.addElement (st.nextToken ());
		}
		catch (REException e)
		{
		    System.out.println ("REException: " + e);
		}
	    }
	    in.close ();
	}
	catch (Exception e)
	{
	    e.printStackTrace ();
	}
    }

    void process (String s)
    {
	messages.append (s);
    }
}
