// Buyer.java
package ld5_2;
import jade.content.ContentElement;
import jade.content.ContentManager;
import jade.content.lang.Codec;
import jade.content.lang.sl.SLCodec;
import jade.content.onto.Ontology;
import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour;
import jade.core.behaviours.SimpleBehaviour;
import jade.gui.GuiAgent;
import jade.gui.GuiEvent;
import ld5_2.ontology.BuyCar;
import ld5_2.ontology.BuyCarMsg;
import ld5_2.ontology.BuyCarResponse;
import ld5_2.ontology.BuyCarResponseMsg;
import ld5_2.ontology.CarList;
import ld5_2.ontology.CarListMsg;
import ld5_2.ontology.CarMaker;
import ld5_2.ontology.CarOntology;
import ld5_2.ontology.CarSearch;
import ld5_2.ontology.CarSearchMsg;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;


public class Buyer extends GuiAgent {

    public static final int SEARCH_EVENT = 1;
    public static final int BUY_EVENT    = 2;
    private transient BuyerGUI gui;
    
    private void print(String data, String elgesenosId) {
        if (elgesenosId != null) {
            System.out.println("A[" + getLocalName() + " | " + elgesenosId + "] " + data);
        } else {
            System.out.println("A[" + getLocalName() + "] " + data);
        }
    }

    private void sendCarSearch(int priceFrom, int priceTo, int yearFrom,  int yearTo, String country) {
        Ontology onto = CarOntology.getInstance();
        Codec codec = new SLCodec();
        
        ACLMessage req = new ACLMessage(ACLMessage.INFORM);
        req.setLanguage(codec.getName()); 
        req.setOntology(onto.getName()); 
        ContentManager cm = getContentManager();
        cm.registerLanguage(codec);
        cm.registerOntology(onto);

        AID a = new AID("Seller", AID.ISLOCALNAME);

        req.clearAllReceiver();
        req.addReceiver(a); 
        req.setConversationId("car-search");

        CarMaker make = new CarMaker();
        make.setGID(1);
        make.setCountry("Japan");
        make.setMakeName("Honda");
        make.setMakeAddress("Tokyo 12/62");

        CarSearch cs = new CarSearch();
        cs.setPriceFrom(priceFrom);
        cs.setPriceTo(priceTo);
        cs.setYearFrom(yearFrom);
        cs.setYearTo(yearTo);
        cs.setCountry(country);

        CarSearchMsg msg = new CarSearchMsg();
        msg.setCarSearchLine(cs);

        try {
            cm.fillContent(req, msg);
            req.addUserDefinedParameter("klase", "CarSearch");
            send(req);
        } catch (Exception ex) {
            print(ex.getMessage(), "sendCarSearch");
            gui.setStatus("error", false);
        }
    }

    private void sendBuyCar(int vin) {
        Ontology onto     = CarOntology.getInstance();
        Codec    codec    = new SLCodec();
        ContentManager cm = getContentManager();
        cm.registerLanguage(codec);
        cm.registerOntology(onto);

        ACLMessage req = new ACLMessage(ACLMessage.INFORM);
        req.setLanguage(codec.getName());
        req.setOntology(onto.getName());
        // req.clearAllReceiver();
        req.addReceiver(new AID("Seller", AID.ISLOCALNAME));
        req.setConversationId("car-buy");

        BuyCar bc = new BuyCar();
        bc.setVIN(vin);
        BuyCarMsg msg = new BuyCarMsg();
        msg.setBuyCarLine(bc);

        try {
            cm.fillContent(req, msg);
            send(req);
        } catch (Exception ex) {
            print(ex.getMessage(), "sendBuyCar");
            gui.setStatus("Error.", false);
        }
    }

    private class WaitForMessagesCarList extends CyclicBehaviour 
    {
        @Override
        public void action() 
        {               
            Ontology onto = CarOntology.getInstance();
            Codec codec = new SLCodec();
            ContentManager cm = getContentManager();
            cm.registerLanguage(codec);
            cm.registerOntology(onto);
            
            MessageTemplate mt = MessageTemplate.MatchConversationId("car-list");
            ACLMessage msg = myAgent.receive(mt);
                        
            if (msg != null) 
            {                
                try
                {                    
                    String pran = msg.getContent();
                    print("Message received: "+pran, "WaitForMessagesCarList");
                    
                    ContentElement c = cm.extractContent(msg);
                    
                    if (c instanceof CarListMsg)
                    {
                        CarListMsg p = (CarListMsg) c;
                        
                        print("buying cars ", "WaitForMessagesCarList");
                        gui.updateCarTable(p);
                    }                
                    else
                    {
                        print("received unknown message: " + pran, "WaitForMessagesCarSearch");
                    }
                } 
                catch (Exception ex)
                {
                    print("Ontology parsing error: "+ ex.getMessage(), "WaitForMessagesCarSearch");
                }
            }
            else block();
        }
    }

    private class WaitForMessagesBuyCarResponseMsg extends CyclicBehaviour 
    {
        @Override
        public void action() 
        {               
            Ontology onto = CarOntology.getInstance();
            Codec codec = new SLCodec();
            ContentManager cm = getContentManager();
            cm.registerLanguage(codec);
            cm.registerOntology(onto);
            
            MessageTemplate mt = MessageTemplate.MatchConversationId("car-buy-res");
            ACLMessage msg = myAgent.receive(mt);       
                        
            if (msg != null) 
            {                
                try
                {                    
                    String pran = msg.getContent();
                    print("Message received: "+pran, "WaitForMessagesBuyCarResponseMsg");
                    
                    ContentElement c = cm.extractContent(msg);
                    
                    if (c instanceof BuyCarResponseMsg)
                    {
                        BuyCarResponseMsg p = (BuyCarResponseMsg) c;
                        BuyCarResponse l = null;
                        
                        l = p.getBuyCarResLine();
                        print("BuyCarResponseMsg: approved=" + l.getIsApproved() + " VIN=" + l.getVIN(), "WaitForBuyResponse");
                        gui.showBuyResult(l); 
                    }                
                    else
                    {
                        print("received unknown message: " + pran, "WaitForMessagesCarSearch");
                    }
                } 
                catch (Exception ex)
                {
                    print("Ontology parsing error: "+ ex.getMessage(), "WaitForMessagesCarSearch");
                }
            }
            else block();
        }
    }
        @Override
    protected void onGuiEvent(GuiEvent ge) {
        switch (ge.getType()) {
 
            case SEARCH_EVENT: {
                int    priceFrom = (Integer) ge.getParameter(0);
                int    priceTo   = (Integer) ge.getParameter(1);
                int    yearFrom  = (Integer) ge.getParameter(2);
                int    yearTo    = (Integer) ge.getParameter(3);
                String country   = (String)  ge.getParameter(4);
                print("SEARCH: price=" + priceFrom + "-" + priceTo
                      + " year=" + yearFrom + "-" + yearTo
                      + " country=" + country, "onGuiEvent");
                sendCarSearch(priceFrom, priceTo, yearFrom, yearTo, country);
                break;
            }
 
            case BUY_EVENT: {
                int vin = (Integer) ge.getParameter(0);
                print("BUY: VIN=" + vin, "onGuiEvent");
                sendBuyCar(vin);
                break;
            }
 
            default:
                print("" + ge.getType(), "onGuiEvent");
        }
    }

    @Override 
    public void setup() {
        gui = new BuyerGUI(this);
        gui.setVisible(true);

        addBehaviour(new WaitForMessagesCarList());
        addBehaviour(new WaitForMessagesBuyCarResponseMsg());

        print("Agent ready", null);
    }

    @Override  
    public void takeDown() 
    {     
    } 
}