/* Murat Yildizoglu
 * Copyright (C) 1996-2001 Murat Yildizoglu.
 * e-mail: yildi[a_t]u-bordeaux4.fr
 * All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for NON-COMMERCIAL purposes
 * and without fee is hereby granted provided that this
 * copyright notice appears in all copies.
 *	Last change:  MY   10 Jul 00    21:47
 */

/**
 * @version 3.2 10 March 2001
 * @author Murat Yildizoglu
 */

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
import java.lang.Math;
import java.util.*;
import corejava.*;
import graph.*;



/**
/* This applet runs the Nelson and Winter's Model
* and prints the evolution of fundamental variables
* on the screen
* @author Murat Yildizoglu (yildi[a_t]u-bordeaux4.fr)
* @version 3.2 10 March 2001
*/

public class NelWinApplet extends Applet
	implements ActionListener
{


   private void adding(Component c, GridBagLayout gbl,
      	GridBagConstraints gbc, int x, int y, int w, int h)
   {  gbc.gridx = x;
      gbc.gridy = y;
      gbc.gridwidth = w;
      gbc.gridheight = h;
      c.setFont(font);
      gbl.setConstraints(c, gbc);
      panel.add(c);
   }

   private void adding2(Component c, GridBagLayout gbl,
      GridBagConstraints gbc, int x, int y, int w, int h)
   {  gbc.gridx = x;
      gbc.gridy = y;
      gbc.gridwidth = w;
      gbc.gridheight = h;
      gbl.setConstraints(c, gbc);
      panel2.add(c);
   }




	public String getAppletInfo()
	{
		return "Name: NelWinApplet\r\n" +
		       "Author: Murat Yildizoglu\r\n";
	}


	public void init()
	{
		setLayout(new BorderLayout());
		//setSize(620,380);


      	GridBagLayout gbl = new GridBagLayout();
      	panel.setLayout(gbl);
      	GridBagConstraints gbc = new GridBagConstraints();
     	gbc.fill = GridBagConstraints.BOTH;
     	gbc.weightx = 0;
      	gbc.weighty = 0;
      	adding(new Label("Capital cost (%)"), gbl, gbc, 0, 0, 1, 1);
      	adding(costField, gbl, gbc, 1, 0, 1, 1);
      	adding(new Label("Dem. coeff. (%)"), gbl, gbc, 2, 0, 1, 1);
      	adding(demcoeffField, gbl, gbc, 3, 0, 1, 1);
      	adding(new Label("Dem. elasticity (%)"),	gbl, gbc, 4, 0, 1, 1);
      	adding(elasticityField, gbl, gbc, 5, 0, 1, 1);
      	adding(new Label("Initial prod. (%)"), gbl, gbc, 0, 1, 1, 1);
      	adding(prodField, gbl, gbc, 1, 1, 1, 1);
      	adding(new Label("Depreciation (%)"), gbl, gbc, 2, 1, 1, 1);
      	adding(depreciationField, gbl, gbc, 3, 1, 1, 1);
      	adding(new Label("Pr. innovation (%)"), gbl, gbc, 4, 1, 1, 1);
      	adding(P_inField, gbl, gbc, 5, 1, 1, 1);
      	adding(new Label("Pr. imitation (%)"), gbl, gbc, 0, 2, 1, 1);
      	adding(P_imField, gbl, gbc, 1, 2, 1, 1);
      	adding(new Label("Dispersion (%)"), gbl, gbc, 2, 2, 1, 1);
      	adding(sdField, gbl, gbc, 3, 2, 1, 1);
      	adding(new Label("Bank (%)"), gbl, gbc, 4, 2, 1, 1);
      	adding(BankField, gbl, gbc, 5  , 2, 1, 1);
      	adding(new Label("Number of periods"), gbl, gbc, 0, 3, 1, 1);
      	adding(TField, gbl, gbc, 1, 3, 1, 1);
      	adding(new Label("Number of firms:"), gbl, gbc, 2, 3, 1, 1);
      	adding(new Label("Innovators:"), gbl, gbc, 3, 3, 1, 1);
      	adding(N_inField, gbl, gbc, 4, 3, 1, 1);
      	adding(new Label("Pure imitators:"), gbl, gbc, 3, 4, 1, 1);
      	adding(N_imField, gbl, gbc, 4, 4, 1, 1);
      	Button button= new Button("Compute");
      	adding(button , gbl, gbc, 5, 4, 1, 1);
		adding(N_imField, gbl, gbc, 4, 4, 1, 1);
 
      	GridBagLayout gbl2 = new GridBagLayout();
      	panel2.setLayout(gbl2);
      	GridBagConstraints gbc2 = new GridBagConstraints();
      	gbc2.fill = GridBagConstraints.BOTH;
      	gbc2.weighty = 0;
      	gbc2.weightx = 0;
      	adding2(new Label("Price Dynamics"),gbl2,gbc2,1,1,1,1);
      	adding2(new Label("Productivity Dynamics"),gbl2,gbc2,2,1,1,1);
      	adding2(new Label("Concentration over capital"),gbl2,gbc2,1,3,1,1);
      	adding2(new Label("Concentration over market shares"),gbl2,gbc2,2,3,1,1);
      	adding2(new Label("Total capital stock of the industry"),gbl2,gbc2,1,5,1,1);
      	adding2(new Label("Average profits of the period"),gbl2,gbc2,2,5,1,1);
      	gbc2.weightx = 100;
      	gbc2.weighty = 100;
      	adding2(graph1,gbl2,gbc2,1,2,1,1);
      	adding2(graph2,gbl2,gbc2,2,2,1,1);
      	adding2(graph3,gbl2,gbc2,1,4,1,1);
      	adding2(graph4,gbl2,gbc2,2,4,1,1);
      	adding2(graph5,gbl2,gbc2,1,6,1,1);
      	adding2(graph6,gbl2,gbc2,2,6,1,1);


		add(panel,"North");
 		add(panel2,"Center");


	     button.addActionListener(this);

	}




   /**
   * The main procedure: Constructs the industry
   * and runs the simulation
   */

   public void actionPerformed(ActionEvent evt)
   {

   	String	arg=evt.getActionCommand();
   	if (arg.equals("Compute")
      	    &&	(costField.isValid()
            && demcoeffField.isValid()
            && elasticityField.isValid()
            && prodField.isValid()
            && depreciationField.isValid()
            && P_inField.isValid()
            && P_imField.isValid()
            && sdField.isValid()
	    && N_inField.isValid()
	    && N_imField.isValid()
	    && TField.isValid()
	    && BankField.isValid()))
         	{
          	Cost = (double) costField.getValue()/100;
          	Dem = (double) demcoeffField.getValue()/100;
          	Eta = (double) elasticityField.getValue()/100;
          	Prod0 = (double) prodField.getValue()/100;
          	Delta = (double) depreciationField.getValue()/100;
          	P_in = (double) P_inField.getValue()/100;
          	P_im = (double) P_imField.getValue()/100;
          	Sigma_in = (double) sdField.getValue()/100;
		N_in = N_inField.getValue();
		N_im = N_imField.getValue();
		T = TField.getValue();
		B = (double) BankField.getValue()/100;

		data_p=new double[T];
		data_pr=new double[T];
		data_hk=new double[T];
		data_hq=new double[T];
		data_indK=new double[T];
		data_indprofin=new double[T];
		data_indprofim=new double[T];
	        N=(N_in+N_im);
		Industry=new EvolFirm[N];


		K0=Math.pow((Dem*Prod0*(N*Eta-1))/(N*Eta*Cost),1/Eta)/(N * Prod0);

          	int i=0;
          	for ( i=0;i <= (N_in-1) ;i++ )
			{
			Industry[i]= new EvolFirm(K0, Prod0, Cost, P_in, P_im, D_in, D_im,
			Sigma_in, B, Delta, Eta);
			}
          	for ( i=(N_in);i<=(N-1)  ;i++ )
			{
			Industry[i]= new EvolFirm(K0, Prod0, Cost, 0, P_im, D_in, D_im,
			Sigma_in, B, Delta, Eta);
			}


		for ( t=1;t<=T ;t++ )
			{
      			Supply=IndSupply();
      			P=demand(Supply);
    				Statistics();
				data_pr[t-1]=  Meanprod/Maxprod;
				data_p[t-1]=  P;
				data_hk[t-1]= HK;
				data_hq[t-1]=  HQ;
				data_indK[t-1]=IndK;
				data_indprofin[t-1]=IndProfIn;
				data_indprofim[t-1]=IndProfIm;


      			for ( i=0;i<=Industry.length-1 ;i++ )
      			{
					Industry[i].imitate(Maxprod);
      			}

      			for ( i=0;i<=Industry.length-1 ;i++ )
      			{
					if (i<=(N_in-1))
						Industry[i].innovate();

					Industry[i].invest(P,Supply,B);
      			}

		}

	plot();


 }
}




  /**
   * Computes the industry supply.
   * @return S
   */
   public double IndSupply()
    {	double S=0;
    		IndK=0;
			for ( int i=0;i<=Industry.length-1 ;i++ )
			{
					S+=Industry[i].supply();
					IndK+=Industry[i].getKapital();
			}
			return S;
    }
 /**
   * Computes the average and maximal productivities of the industry
   * @return Meanprod
   * @return Maxprod
   * @return HQ
   * @return HK
   * @return IndK
   * @return IndProf
   */
	 void Statistics()
		 {
			Maxprod=0;
			Meanprod=0;
		 	HK=0;
		 	HQ=0;
		 	IndProfIn=0;
		 	IndProfIm=0;
			for ( int i=0;i<=Industry.length-1 ;i++ )
			{
					double prd=Industry[i].getprod();
					if (prd>Maxprod)
							Maxprod=prd;
					Meanprod+=prd;
					if (i<=N_in - 1)
						IndProfIn+=Industry[i].getProfit(P);
					else
						IndProfIm+=Industry[i].getProfit(P);

					HQ+=Math.pow(Industry[i].supply()/Supply,2.0);
					HK+=Math.pow((double)(Industry[i].getKapital()/IndK),2.0);
			}
			Meanprod/=Industry.length;
			HQ=1/HQ;
			HK=1/HK;
                        if (N_in > 1)
                          {
                          IndProfIn/=N_in;
                          }
                        if (N_im > 1)
                          {
                          IndProfIm/=N_im;
                          }
		 }

   /**
   * Demand function is used to compute the market price
   * @param S
   */
   public double demand(double s)
    {
       return Dem/Math.pow(s,Eta);
    }


   /** This function generates the graphics.
   */

   void plot()
	{
	int count =0,
			j=0;
			t=0;
			data_prix=new double[2*T];
			data_prod=new double[2*T];
			data_HK=new double[2*T];
			data_HQ=new double[2*T];
			data_INDK=new double[2*T];
			data_INDPROFIN=new double[2*T];
			data_INDPROFIM=new double[2*T];


	 for(j=0; j < T; j++)
	{
	data_prix[count]=j;
     	data_prix[count+1]=data_p[j];

	data_prod[count]=j;
	data_prod[count+1]=data_pr[j];

	data_HK[count]=j;
	data_HK[count+1]=data_hk[j];

	data_HQ[count]=j;
	data_HQ[count+1]=data_hq[j];

	data_INDK[count]=j;
	data_INDK[count+1]=data_indK[j];

	data_INDPROFIN[count]=j;
	data_INDPROFIN[count+1]=data_indprofin[j];

	data_INDPROFIM[count]=j;
	data_INDPROFIM[count+1]=data_indprofim[j];


	count+=2;
	}
		graph1.detachDataSets();
		graph2.detachDataSets();
		graph3.detachDataSets();
		graph4.detachDataSets();
		graph5.detachDataSets();
		graph6.detachDataSets();

		graph1.detachAxes();
		graph2.detachAxes();
		graph3.detachAxes();
		graph4.detachAxes();
		graph5.detachAxes();
		graph6.detachAxes();

		graph1.repaint();
		graph2.repaint();
		graph3.repaint();
		graph4.repaint();
		graph5.repaint();
		graph6.repaint();

		data1=new DataSet();
		data2=new DataSet();
		data3=new DataSet();
		data4=new DataSet();
		data5=new DataSet();
		data6in=new DataSet();
		data6im=new DataSet();

		try{
		data1=graph1.loadDataSet(data_prix,T);
		data2=graph2.loadDataSet(data_prod,T);
		data3=graph3.loadDataSet(data_HK,T);
		data4=graph4.loadDataSet(data_HQ,T);
		data5=graph5.loadDataSet(data_INDK,T);
		data6in=graph6.loadDataSet(data_INDPROFIN,T);
		data6im=graph6.loadDataSet(data_INDPROFIM,T);

		}catch(Exception e){
			this.showStatus("Error while appending data!");
			return;
		}


	graph1.drawzero=true;
	graph1.drawgrid=true;
	graph1.clearAll=true;
	graph1.setGraphBackground(new Color(255,255,255));
	graph1.setDataBackground(new Color(255,255,255));

	data1.linecolor=new Color(0,0,255);
	data1.linestyle=1;

	xaxis=graph1.createAxis(Axis.BOTTOM);
	xaxis.attachDataSet(data1);
	xaxis.setTitleText("t");
	xaxis.setLabelFont(font);

	yaxis=graph1.createAxis(Axis.LEFT);
	yaxis.attachDataSet(data1);
	yaxis.setTitleText("Market price");
        yaxis.setTitleFont(font2);
	yaxis.setLabelFont(font);
	yaxis.force_end_labels = true;
	yaxis.minimum=0.0;


	graph2.drawzero=true;
	graph2.drawgrid=true;
	graph2.clearAll=true;
	graph2.setGraphBackground(new Color(255,255,255));
	graph2.setDataBackground(new Color(255,255,255));

	data2.linecolor=new Color(0,0,255);
	data2.linestyle=1;

	xaxis2=graph2.createAxis(Axis.BOTTOM);
	xaxis2.attachDataSet(data2);
	xaxis2.setTitleText("t");
	xaxis2.setLabelFont(font);

	yaxis2=graph2.createAxis(Axis.LEFT);
	yaxis2.attachDataSet(data2);
	yaxis2.setTitleText("Average Prod / Maximal Prod");
	yaxis2.setLabelFont(font);
        yaxis2.setTitleFont(font2);
	yaxis2.minimum=0.0;
	yaxis2.maximum=1.0;
	yaxis2.force_end_labels = true;
	yaxis2.minimum=0.0;
	yaxis2.maximum=1.0;


	graph3.drawzero=true;
	graph3.drawgrid=true;
	graph3.clearAll=true;
	graph3.setGraphBackground(new Color(255,255,255));
	graph3.setDataBackground(new Color(255,255,255));
	data3.linecolor=new Color(0,0,255);
	data3.linestyle=1;

	xaxis3=graph3.createAxis(Axis.BOTTOM);
	xaxis3.attachDataSet(data3);
	xaxis3.setTitleText("t");
	xaxis3.setLabelFont(font);

	yaxis3=graph3.createAxis(Axis.LEFT);
	yaxis3.attachDataSet(data3);
	yaxis3.setTitleText("1/H (Capital)");
        yaxis3.setTitleFont(font2);
	yaxis3.setLabelFont(font);
	yaxis3.minimum=0.0;
	yaxis3.maximum=N;
	yaxis3.force_end_labels = true;


	graph4.drawzero=true;
	graph4.drawgrid=true;
	graph4.clearAll=true;
	graph4.setGraphBackground(new Color(255,255,255));
	graph4.setDataBackground(new Color(255,255,255));
	data4.linecolor=new Color(0,0,255);
	data4.linestyle=1;

	xaxis4=graph4.createAxis(Axis.BOTTOM);
	xaxis4.attachDataSet(data4);
	xaxis4.setTitleText("t");
	xaxis4.setLabelFont(font);

	yaxis4=graph4.createAxis(Axis.LEFT);
	yaxis4.attachDataSet(data4);
	yaxis4.setTitleText("1/H (Output)");
        yaxis4.setTitleFont(font2);
	yaxis4.setLabelFont(font);
	yaxis4.minimum=0.0;
	yaxis4.maximum=N;
	yaxis4.force_end_labels = true;


	graph5.drawzero=true;
	graph5.drawgrid=true;
	graph5.clearAll=true;
	graph5.setGraphBackground(new Color(255,255,255));
	graph5.setDataBackground(new Color(255,255,255));

	data5.linecolor=new Color(0,0,255);
	data5.linestyle=1;

	xaxis5=graph5.createAxis(Axis.BOTTOM);
	xaxis5.attachDataSet(data5);
	xaxis5.setTitleText("time");
	xaxis5.setLabelFont(font);

	yaxis5=graph5.createAxis(Axis.LEFT);
	yaxis5.attachDataSet(data5);
	yaxis5.setTitleText("Capital stock");
        yaxis5.setTitleFont(font2);
	yaxis5.setLabelFont(font);
	yaxis5.minimum=0.0;
	yaxis5.force_end_labels = true;


	graph6.drawzero=true;
	graph6.drawgrid=true;
	graph6.clearAll=true;
	graph6.setGraphBackground(new Color(255,255,255));
	graph6.setDataBackground(new Color(255,255,255));

	data6in.linecolor=new Color(255,0,0);
	data6in.linestyle=1;

	data6im.linecolor=new Color(0,0,255);
	data6im.linestyle=1;

	xaxis6=graph6.createAxis(Axis.BOTTOM);
	xaxis6.attachDataSet(data6im);
	xaxis6.setTitleText("t");
	xaxis6.setLabelFont(font);
	xaxis6.attachDataSet(data6in);


	yaxis6in=graph6.createAxis(Axis.LEFT);
	yaxis6in.attachDataSet(data6in);
	yaxis6in.setTitleText("Innovators");
	yaxis6in.setTitleColor(new Color(255,0,0));
        yaxis6in.setTitleFont(font2);
	yaxis6in.setLabelFont(font);
        yaxis6in.setLabelColor(new Color(255,0,0));
        yaxis6in.minimum=0.0;
	yaxis6in.force_end_labels = true;



	yaxis6im=graph6.createAxis(Axis.RIGHT);
	yaxis6im.attachDataSet(data6im);
	yaxis6im.setTitleText("Imitators");
	yaxis6im.setTitleColor(new Color(0,0,255));
        yaxis6im.setTitleFont(font2);
	yaxis6im.setLabelFont(font);
        yaxis6im.setLabelColor(new Color(0,0,255));
	yaxis6im.minimum=0.0;
	yaxis6im.force_end_labels = true;





		graph1.repaint();
		graph2.repaint();
		graph3.repaint();
		graph4.repaint();
		graph5.repaint();
		graph6.repaint();

}

   private IntTextField costField
      = new IntTextField(16,5);
   private IntTextField demcoeffField
      = new IntTextField(6700,10);
   private IntTextField elasticityField
      = new IntTextField(100,4);
   private IntTextField prodField
      = new IntTextField(16,5);
   private IntTextField depreciationField
      = new IntTextField(3,3);
   private IntTextField P_inField
      = new IntTextField(5,3);
   private IntTextField P_imField
      = new IntTextField(3,3);
   private IntTextField sdField
      = new IntTextField(5,5);
    private IntTextField N_inField
      = new IntTextField(4,3);
    private IntTextField N_imField
      = new IntTextField(4,3);
    private IntTextField TField
      = new IntTextField(300,4);
    private IntTextField BankField
      = new IntTextField(100, 4);


   public int N_in,N_im,N,T,t=0;


     double
       Cost,
       B,
       P_im,
       P_in,
       D_im=1.25,
       D_in=0.125,
       Eta,
       Delta,
       Sigma_in,
       Prod0=0.16,
       K0,
       Dem,
       Maxprod=0,
       Meanprod=0,
	  IndK=0,
	  IndProfIn=0,
	  IndProfIm=0,
       Supply=0,
       P=0,
	  HK=0,
	  HQ=0;


      EvolFirm[] Industry;
	   	public Panel panel = new Panel();
	   	public Panel panel2 = new Panel();
			Graph2D graph1=new Graph2D();
			Graph2D graph2=new Graph2D();
			Graph2D graph3=new Graph2D();
			Graph2D graph4=new Graph2D();
			Graph2D graph5=new Graph2D();
			Graph2D graph6=new Graph2D();
	    DataSet data1,data2,data3,data4,data5,data6in,data6im;
	    Axis xaxis,xaxis2,xaxis3,xaxis4,xaxis5,xaxis6;
	    Axis yaxis,yaxis2,yaxis3,yaxis4,yaxis5,yaxis6in,yaxis6im;
	    Label title,title2;
			public double data_p[], data_pr[], data_hk[],data_hq[],
				data_indK[],data_indprofin[],data_indprofim[];
			public double data_prix[],data_prod[],data_HK[],data_HQ[],
				data_INDK[],data_INDPROFIN[],data_INDPROFIM[];
			public Font font = new Font("TimesRoman",Font.PLAIN,11);

                        public Font font2 = new Font("Arial",Font.PLAIN,9);




}