package tiptopTool;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.HttpURLConnection;
import java.net.URLConnection;
import java.io.*;
import java.util.Observable;
import java.util.Observer;

/**
 * Created by IntelliJ IDEA.
 * User: Igor
 * Date: 11.12.2005
 * Time: 13:45:51
 * To change this template use File | Settings | File Templates.
 */

// This class downloads a file from a URL.
public class Download2 extends Observable implements Runnable
{

// Max size of download buffer.
    private static final int MAX_BUFFER_SIZE = 1024;

// These are the status names.
    public static final String STATUSES[] = {"Загрузка", "Пауза", "Завершенно", "Отменено", "Ошыбка"};

// These are the status codes.
    public static final int DOWNLOADING = 0;
    public static final int PAUSED = 10;
    public static final int COMPLETE = 2;
    public static final int CANCELLED = 3;
    public static final int ERROR = 4;

    public static URL urla;
    public URL url; // download URL //bylo private
    public String fileName; //путь к файлу
    public String description="";
    private int size; // size of download in bytes
    private int downloaded; // number of bytes downloaded
    private int status; // current status of download

    private byte buffer[];//if save in the buffer
// Constructor for Download.

    public int getDownloaded()
    {
        return downloaded;
    }

    public Download2(URL url,String fileName)
    {
        this.url = url;
        this.fileName=fileName;
        size = -1;
        downloaded = 0;
        status = DOWNLOADING;
    }
// Get this download's URL.
    public String getUrl()
    {
        return url.toString();
    }
// Get this download's size.
    public int getSize()
    {
        return size;
    }
// Get this download's progress.
    public float getProgress()
    {
        return ((float) downloaded / size) * 100;
    }
// Get this download's status.
    public int getStatus()
    {
        return status;
    }
// Pause this download.
    public void pause()
    {
        status = PAUSED;
        stateChanged();
    }
// Resume this download.
    public void resume()
    {
        status = DOWNLOADING;
        stateChanged();
        download();
    }
// Cancel this download.
    public void cancel()
    {
        status = CANCELLED;
        stateChanged();
    }
// Mark this download as having an error.
    private void error()
    {
        status = ERROR;
        stateChanged();
    }
// Start or resume downloading.
    public void download()
    {
        Thread thread = new Thread(this);
        thread.start();
    }
// Download
    public void run()
    {
        //System.out.println("run");
        RandomAccessFile file = null;
        InputStream stream = null;

        try
        {
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("Range","bytes=" + downloaded + "-");// Specify what portion of file to download.
            // Connect to server.
            connection.connect(); //System.out.println("connection to " + connection.getContentType()+" ResponseCode " + connection.getResponseCode());
            if (connection.getResponseCode() / 100 != 2) // провери отве севера
            {
                error();
            }
            // Connect to server.
            //connection.connect();
            //System.out.println(connection.getHeaderField(0).toString());
            //System.out.println("Тип пакета = " + connection.getContentType());
            //System.out.println("Заголовок = " + connection.getHeaderField(1));
            //System.out.println("Класс " + connection.toString());
            //System.out.println("Код ответа " + connection.getResponseCode());

// Check for valid content length.
            int contentLength = connection.getContentLength();
            //System.out.println("Размер загружаемого файла =" + contentLength);
            if (contentLength < 1)
            {
                error();
            }
// Set the size for this download if it
//hasn't been already set.
            if (size == -1)
            {
                size = contentLength;
                stateChanged();
            }

// Open file and seek to the end of it.
            if (!fileName.equals(""))
            {
                file = new RandomAccessFile(fileName, "rw");
                file.seek(downloaded);
            }
            if (fileName.equals("")) //фаил не задан сохраняем в буфер
            {
                this.buffer = new byte[size];
            }

            stream = connection.getInputStream();
            while (status == DOWNLOADING)
            {
                if (!fileName.equals("")) //если сохраняем в фаил
                {
                    byte buffer[];
                    if (size - downloaded > MAX_BUFFER_SIZE)
                    {
                        buffer = new byte[MAX_BUFFER_SIZE];
                    } else
                    {
                        buffer = new byte[size - downloaded];
                    }
                    // Read from server into buffer.
                    int read = stream.read(buffer);
                    if (read == -1)
                        break;
                    // Write buffer to file.
                    file.write(buffer, 0, read);
                    downloaded += read;
                }
                if (fileName.equals("")) //если сохраняем в буфер
                {
                    byte buffer[];
                    if (size - downloaded > MAX_BUFFER_SIZE)
                    {
                        buffer = new byte[MAX_BUFFER_SIZE];
                    } else
                    {
                        buffer = new byte[size - downloaded];
                    }
                    // Read from server into buffer.
                    int read = stream.read(buffer);
                    if (read == -1)
                        break;
                    // Write small buffer to big buffer.
                    for(int i=downloaded;i<downloaded+read;i++)
                    {
                        this.buffer[i]=buffer[i-downloaded];
                    }                    
                    downloaded += read;
                }
                stateChanged();
            }
// Change status to complete if this point was
//reached because downloading has finished.
            if (status == DOWNLOADING)
            {
                status = COMPLETE;
                stateChanged();
            }
        } catch (Exception e)
        {
            error();
        } finally
        {
// Close file.
            if (file != null)
            {
                try
                {
                    file.close();
                } catch (Exception e)
                {
                }
            }
// Close connection to server.
            if (stream != null)
            {
                try
                {
                    stream.close();
                } catch (Exception e)
                {
                }
            }
        }
    }

    /**
     * get loaded data
     * @return Stream data
     */
    public DataInputStream getData()
    {
        if (fileName.equals("")) //если сохраняем в буфер
        {
            return new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(buffer)));
        }else
        if (!fileName.equals("")) //если сохраняем в буфер
        {
            try
            {
                //System.out.println("Запрошенные данные = "+fileName);
                return new DataInputStream(new BufferedInputStream(new FileInputStream(fileName)));
            } catch (FileNotFoundException e)
            {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
        return null;
    }


// Notify observers that this download's status has changed.
    private void stateChanged()
    {
        setChanged();
        notifyObservers(this);
        //System.out.println("Загруженно = "+downloaded+" из="+size);
    }

    public static void main(String args[])
    {
        try
        {
            URL a = new URL("http://tiptopcity.com/java/d.php");
            Download2 pobieranie = new Download2(a,"d.php");
            pobieranie.download();

        } catch (MalformedURLException e)
        {
            System.out.println("Bad URL gayos");
        }
    }
}