package org.havi.ui;

import java.awt.*;
import java.io.*;
import java.net.URL;
import org.havi.ui.event.*;
import java.util.*;

import org.openmhp.util.Out;

import javax.imageio.ImageIO; // miknov

/**
* @author tejopa
* @date 15.2.2004
* @status partially implemented
* @module internal, graphics
* TODO: map image loading and displaying through adaptation layer
* @priority high
* @date 28.9.2004 Changed to load Imagemagick's directory from properties file. Property can be set from Application Manager.
* @date 29.9.2004 Added possibility load any image to background
*/
public class HBackgroundImage extends Component {

    private Image image;
    private int width;
    private int height;
    final String TEMP_FRAME = "temp_iframe.m2v";
    final String TEMP_JPG = "temp_iframe.jpg";    

	int TEMP_INDEX = 0;
	int TEMP_JPGS_MAX = 10;

    public HBackgroundImage(String s) {

		loadDefault();

		String FS = File.separator;
		Properties p = loadProperties(org.openmhp.system.Constants.ROOT+FS+"static"+FS+"openmhp.properties");
		String ss = p.getProperty("iframe_convert",null);
		ss = "convert"; // miknov
		if (ss.length()>0) {
			Out.printMe(Out.TRACE,"User has set convert program: "+ss);
			convert(s);
		} 
		else {
			Out.printMe(Out.TRACE,"NOTE: I-frame conversion program has NOT been set.");
		}

		String useimage = p.getProperty("use_background_image",null);
		if (useimage!=null) {
			Out.printMe(Out.TRACE,"useimage was not null ###############");
			if (useimage.indexOf("true")!=-1) {
				Out.printMe(Out.TRACE,"useimage was TRUE ###############");
				loadBackgroundImage(s);	
			}
		}

  		Container backgroundlayer = org.openmhp.system.MHPDevice.getBackgroundLayer();

        setBounds(0, 0, backgroundlayer.getWidth(), backgroundlayer.getHeight());

        //HBackgroundImage hbackgroundimage = this;
        //backgroundlayer.add(hbackgroundimage);

		setVisible(true);
        repaint();
    }

	private void loadDefault() {
		image = loadImage(org.openmhp.system.Constants.ROOT+java.io.File.separator+org.openmhp.system.Constants.BACKGROUND_IMAGE,null,this);
	}


	/** Method loads any picture file and places it to the background
	* @author tejopa
	* @date 29.9.2004
	*/
	private void loadBackgroundImage(String s) {
        Image temp = loadImage(s, null, this);

		if (temp.getWidth(null)>0) {
			image = temp;
		}
	}

	private void convert(String s) {
		String s1 = (new File("")).getAbsolutePath();
        String s2 = System.getProperty("file.separator", "\\");
        String s3 = s.substring(0, s.lastIndexOf(".")) + ".jpg";

        String source = "";
        String destination = "";
        if (new File(s).exists()) {
			//Out.println(this,"Filename was already in right format");
			source = s;
			destination = s3;
		} else {
			source = s1 + s2 + s;
			destination = s1 + s2 + s3;
		}

        String as[] = {
            org.openmhp.system.Constants.IMAGEMAGICK,
	    // "-colors 256", // miknov
	    // "-dither", // miknov
	    source, destination
        };

		Out.println(this,"original : "+source);
        Out.println(this,"new      : "+destination);

        try    {
            Runtime runtime = Runtime.getRuntime();
            Process process = runtime.exec(as);

	    // miknov: consume convert process output...
	    BufferedReader pr = new BufferedReader(new InputStreamReader(process.getInputStream()));
	    String line = pr.readLine();
	    while (line != null) {
		// System.out.println(pOutLine);
		line = pr.readLine();
	    }
	    process.waitFor();
	    // ...miknov
        }
        catch(Exception exception)        {
            exception.printStackTrace();
        }
        Out.println(this, "Converted " + source + " to jpg");

        Image temp = loadImage(destination, null, this);

		if (temp.getWidth(null)>0) {
			image = temp;
		}
	}

	private void createFile(String s, String dst) {

		try {
	//		org.openmhp.system.Constants.ROOT+File.separator+TEMP_FRAME);
	        String s1 = (new File("")).getAbsolutePath();
	        String s2 = System.getProperty("file.separator", "\\");
	        String s3 = s.substring(0, s.lastIndexOf(".")) + ".jpg";
	
	        String source = "";
	        String destination = "";
	        if (new File(s).exists()) {
				//Out.println(this,"Filename was already in right format");
				source = s;
				//destination = s3;
				destination = dst;

			} else {
				source = s1 + s2 + s;
				destination = s1 + s2 + s3;
			}
	
				File t = new File(destination);
				if (t.exists()) {
					t.delete();
			//		Out.println(this, "DELETED "+destination);
				}
	
	        String as[] = {
	            org.openmhp.system.Constants.IMAGEMAGICK, source, destination
	        };
	
	      	Out.println(this,"original : "+source);
	        Out.println(this,"new      : "+destination);
	
	        try    {
	            Runtime runtime = Runtime.getRuntime();
	            Process process = runtime.exec(as);
	        }
	        catch(Exception exception)        {
	            exception.printStackTrace();
	        }
	        
	        //Out.println(this, "Converted " + source + " to jpg");
	
			while (!(new File(destination).exists())) {
				try {
					Thread.currentThread().sleep(1000);
					System.out.print(".");	
				}
				catch (Exception e) {
					System.out.println(e);	
				}	
			}
			System.out.println("");
			//Out.println(this, "File " + destination + " exists");
		}
		catch (Exception e) {
			System.out.println(e);
		}		
	}

    public HBackgroundImage(byte[] data)    {
		//Out.printMe(Out.TODO,"constructor bytes[]");
		loadDefault();
		saveBytes(data);

		int rnd = (int)(Math.random()*10);

		String s1 = org.openmhp.system.Constants.ROOT+File.separator+TEMP_FRAME;

    	createFile(s1,org.openmhp.system.Constants.ROOT+File.separator+""+rnd+".jpg");    
		
		String s2 = org.openmhp.system.Constants.ROOT+File.separator+""+rnd+".jpg";

		//createFile(s1,org.openmhp.system.Constants.ROOT+File.separator+TEMP_JPG);    
		
		//String s2 = org.openmhp.system.Constants.ROOT+File.separator+TEMP_JPG;


        Image temp = loadImage(s2, null, this);
		while (temp==null) {
			//System.out.println("again");
			saveBytes(data);
	
			rnd = (int)(Math.random()*10);
			//s = org.openmhp.system.Constants.ROOT+File.separator+TEMP_FRAME;
	    	createFile(s1,org.openmhp.system.Constants.ROOT+File.separator+""+rnd+".jpg");    
			//s = org.openmhp.system.Constants.ROOT+File.separator+""+rnd+".jpg";			
			temp = loadImage(s2, null, this);
		}
/*
		while (temp.getWidth(null)<=0) {
			try {
				Thread.currentThread().sleep(100);
				System.out.print("*");	
			}
			catch (Exception e) {
				System.out.println(e);	
			}	
		}
*/
		if (temp.getWidth(null)>0) {
			image = temp;
		}


		Container backgroundlayer = org.openmhp.system.MHPDevice.getBackgroundLayer();

        setBounds(0, 0, backgroundlayer.getWidth(), backgroundlayer.getHeight());

        //HBackgroundImage hbackgroundimage = this;
        //backgroundlayer.add(hbackgroundimage);

		setVisible(true);
        validate();
        repaint();


	}

    public HBackgroundImage(URL url)    {
		Out.printMe(Out.TODO,"constructor URL");
	}

    public void load(HBackgroundImageListener hbackgroundimagelistener)    {
		Out.printMe(Out.TRACE,hbackgroundimagelistener.toString());

		if (getWidth()!=0) {
			hbackgroundimagelistener.imageLoaded(new HBackgroundImageEvent((Object)this,HBackgroundImageEvent.BACKGROUNDIMAGE_LOADED));
		}
    }

    public int getHeight()    {
		return super.getHeight();
	}

    public int getWidth()    {
		return super.getWidth();
	}

    public void flush()    {
		Out.printMe(Out.TODO);
    	image = null;
    	width = -1;
    	height = -1;
    }

    private Image loadImage(String s, URL url, Component component)    {
		Out.printMe(Out.TRACE,"loadImage : "+s);
        MediaTracker mediatracker = new MediaTracker(component);
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Image image1 = null;
        if(s != null) {
	    try { // miknov...
		image1 = ImageIO.read(new File(s));
	    } catch (IOException e) {
		e.printStackTrace();
	    } // ...miknov

		
	    /* miknov: commented out
        	try {
            	image1 = toolkit.getImage(s);
            	mediatracker.addImage(image1, 0);
            }
            catch (Exception e) {
            	System.out.println(e);	
            }
	    */

            /*
            try
            {
                File file = new File(s);
                FileReader filereader = new FileReader(file);
            }
            catch(Exception exception)            {
                Out.printMe(Out.ERROR,exception.toString());
            }
            */
        } else
        if(url != null) {
	    /* miknov: commented out
            image1 = toolkit.getImage(url);
	        mediatracker.addImage(image1, 0);
	    */

	    try { // miknov...
		image1 = ImageIO.read(url);
	    } catch (IOException e) {
		e.printStackTrace();
	    } // ...miknov
        }

	/* miknov: commented out
        try
        {
            //mediatracker.waitForID(0);
            mediatracker.waitForAll();

        }
        catch(Exception exception1)        {
            Out.printMe(Out.ERROR,exception1.toString());
        }
	*/

        System.out.println(image1.getWidth(component)+"x"+image1.getHeight(component));
        if (image1.getWidth(component)==-1||image1.getHeight(component)==-1) {
        	return null;	
        }
        return image1;
    }



    public void paint(Graphics g)    {
		//Out.printMe(Out.TRACE,""+getWidth()+"x"+getHeight());
        if(image != null) {
    		g.fillRect(0,0,	getWidth(), getHeight());
            g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
    	} 
    	else {
			System.out.println("image was NULL");		
    		g.fillRect(0,0,	getWidth(), getHeight());
    	}
    }

	/* save bytes */
	public boolean saveBytes(byte[] byteArray) {
		RandomAccessFile fileout = null;
		try {
			String filename = org.openmhp.system.Constants.ROOT+File.separator+TEMP_FRAME;
			
			File temp = new File(filename);
			if (temp.exists()) {
				temp.delete();
			}
						
			fileout = new RandomAccessFile(filename,"rw");
			if (new File(filename).exists()) {
				fileout.write(byteArray,0,byteArray.length);
				fileout.setLength(byteArray.length);
				return true;
			}
			else {
				return false;
			}

		}
		catch (Exception e) { return false; }
	}


	public static Properties loadProperties(String filename) {
		Properties p = new Properties();
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(filename);
			try {	p.load(fis);	}
			catch (IOException e) {
				System.out.println(e.toString());
				}
			}
		catch (Exception e) {
			Out.printMe(Out.ERROR,"Error while loading properties file >"+filename+"< "+e.toString());
			}
		//System.out.println("Properties file >"+filename+"< loaded.");
		return p;
	}

}
