/*  Agent koji prima i salje poruke pomocu Eventa
 */
package Project5;

import COM.meitca.concordia.*;
import COM.meitca.concordia.collaborate.*;
import COM.meitca.concordia.event.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.lang.Long;
 
public class FetchingAgent
    extends CollaboratorAgent {

    // A reference to the group of which we are a member
    private AgentGroup      agentGroup;
	protected
		URL url;								//helper
		URLConnection http;						//helper
		//String Datum;			
		Vector urls;							//urls to be scanned
		Vector lmd;								//last modified dates
		int cur, url_no;						//current url pointer, stack pointer
		volatile boolean jos;					//semaphore for stopping agent



    /**
     * Constructs an FetchingAgent.
     */
    public FetchingAgent(AgentGroup agentGroup)
        throws java.rmi.RemoteException {
		//vrti se u petlji dok ne postane true
        // Calling super with a reference to an AgentGroup causes the
        // newly created  agent to join the group
        super(agentGroup);
        this.agentGroup = agentGroup;
		
		jos=true;		
		cur = 0; url_no = 0;
		urls=new Vector();
		lmd=new Vector();
        
        try {
            makeEventHandler(true);
        } catch (EventHandlerException e) {
            System.err.println("FetchingAgent: Error making event handler "  + e);
            e.printStackTrace(System.err);
        }
    }

    /**
     * This is the method of the agent which appears in its Itinerary.  This
     * agent simply travels to a server and then waits for an
     * AgentTerminateEvent to be posted to the group.
     */
    public void run() {

        synchronized (this) {										//wait for the task
            try {													//sent in PorukaZaFA
	            this.wait();
		    } catch (InterruptedException e) {}
		}

		while(jos){													//loop until receive event PorukaStopFA
			try {													//note: jos is volatile
				if(Changed()){										//if changed send event to Monitor
					System.out.println("FetchingAgent: Salje poruku za Monitora: "+url.toString());
					postEvent(agentGroup, new PorukaZaMonitor("Menjano: "+url.toString()));
				}
				Thread.currentThread().sleep(2000);					//sleep 2 secs before next url
	        } catch (Exception e) {
		        System.err.println("FetchingAgent: Error posting event "  + e);
			    e.printStackTrace(System.err);
			}
		}
		System.out.println("FetchingAgent: Finishing.");			//this is reached whe received event PorukaStopFA
    }

    /**
     * This is the method which will be invoked by the AgentGroup when
     * an event is posted to the group.  This method runs in a seperate
     * thread from our primary thread of execution.  This thread is
     * known as the agent's event handling thread.
     */
    public void handleEvent(EventType event)
        throws EventException {
		String pom=new String();

        if (event instanceof PorukaZaFA) {
			pom=event.getEventDescription();
            System.out.println("FetchingAgent: Primio sam sledecu poruku: " + pom);
			try {
				//url=new URL(pom);
				lmd.insertElementAt(new Long(0), url_no);			//add new date of last modification
				urls.insertElementAt(new URL(pom),url_no++);		//add new url
	        } catch (Exception e) {
				System.err.println("URL: "  + e);
			    e.printStackTrace(System.err);
			}

            // Wake up the primary thread by making a call to
            // Object.notifyAll  The primary thread has been previously
            // suspended by a call to Object.wait.
            synchronized (this) {
                this.notifyAll();
            }
        }
        else if (event instanceof PorukaStopFA) {							//Event to stop agent
			pom=event.getEventDescription();
            System.out.println("FetchingAgent: Primio sam sledecu poruku: " + pom);
			jos=false;
        }
		
    }

	public boolean Changed(){										//called when seek for changes
		return getData();
	}
	
	//This should fetch data from server
	public boolean getData()	{
		Long old_date;
		long new_date;
		boolean ret=false;
		try{
			if(url_no>0){
				//System.out.println(cur);
				url=(URL)urls.elementAt(cur);						//check one url at time
				http=url.openConnection();							//open connection
				old_date=(Long)lmd.elementAt(cur);					//previous date of last modification
				new_date=http.getLastModified();					//current date of last modification
				lmd.setElementAt(new Long(new_date), cur);			//set current date of last modification
				cur++; cur%=url_no;									//point to next url
				ret=(old_date.longValue()==new_date)?false:true;	//if equal not changed
				//System.out.print(cur);
				//System.out.print(old_date.longValue());
				//System.out.println(new_date);
			}

		} catch (Exception e) {
			System.err.println("GetData: " + e.getMessage());
			e.printStackTrace();
		}
		
		return ret;
	
	}

}




