/***************************************************************
 * Name:      qcopyMain.cpp
 * Purpose:   Code for Application Frame
 * Author:    Qumbetlian (qumbetlian@yahoo.com)
 * Created:   2007-09-20
 * Copyright: Qumbetlian (www.qumbetlian.3x.ro)
 * License:   GPL
 **************************************************************/

#include "copyThread.h"
#include "qcopyMain.h"

//(*InternalHeaders(copyThread)
#include <wx/string.h>
#include <wx/dialog.h>
#include <wx/log.h>
#if !defined __WXMSW__
#   define O_BINARY 0
#endif
//*)

const wxEventType myEVT_GAUGE_FILLING_CHANGE = wxNewEventType();

copyThread::copyThread(qcopyDialog *parent_arg, const char *srcFileName_arg, const char *destFileName_arg, int resolution_arg, bool cont_arg, wxSemaphore *semaphore)
{
    parent = parent_arg;
    srcFileName = new char[(strlen(srcFileName_arg) + 1) * sizeof(char)];
    strcpy(srcFileName, srcFileName_arg);
    destFileName = new char[(strlen(destFileName_arg) + 1) * sizeof(char)];
    strcpy(destFileName, destFileName_arg);
    gaugeFillingEvent gfevent;
    resolution = resolution_arg;
    continuation = cont_arg;
    semaphore1 = semaphore;
    Create();
}

copyThread::~copyThread()
{
    delete[] srcFileName;
    delete[] destFileName;
}

void* copyThread::Entry()
{
	char *buffer;
	int inFileHandle, outFileHandle, nr;
	long inFileLength, i = 0;
	double div, count;
	struct stat file_stat;
    semaphore1->Wait();
	inFileHandle = open(srcFileName, O_RDONLY|O_BINARY);
	if(inFileHandle == -1){
	    wxLogError(wxString::Format("%s on opening \'%s\'", strerror(errno), srcFileName));
		gfevent.setStatus(STOPPED);
		Exit(0);
	}
    if(continuation)
    {
        outFileHandle = open(destFileName, O_WRONLY|O_APPEND|O_BINARY);
        if(outFileHandle == -1)
        {
            wxLogError(wxString::Format("%s on opening \'%s\'", strerror(errno), destFileName));
            gfevent.setStatus(STOPPED);
            Exit(0);
        }
    }
    else
    {
        outFileHandle = open(destFileName, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IREAD|S_IWRITE);
        if(outFileHandle == -1)
        {
            wxLogError(wxString::Format("%s on creating \'%s\'", strerror(errno), destFileName));
            gfevent.setStatus(STOPPED);
            Exit(0);
        }
    }

	buffer = (char *)malloc(resolution);
	fstat(outFileHandle, &file_stat);
	if(continuation) i = file_stat.st_size;
	fstat(inFileHandle, &file_stat);
	inFileLength = file_stat.st_size;
	div = inFileLength/100;
	count = div * floor(i / div);
	lseek(inFileHandle, i, SEEK_SET);
	gfevent.setFillingDegree((int) round(i/div));
	wxPostEvent(parent, gfevent);
	while(i < inFileLength && semaphore1->TryWait() == wxSEMA_BUSY){
		if((nr = read(inFileHandle, buffer, 2)) == -1) // A intervenit o eroare in citire
        {
            i += resolution;
            memset(buffer, 0, resolution);
            write(outFileHandle, buffer, resolution);
            lseek(inFileHandle, i, SEEK_SET);
		}
		else // Citirea s-a facut fara erori
		{
            i += nr;
            write(outFileHandle, buffer, nr);
        }
        if(i >= count)
        {
			count = count + div;
            gfevent.setFillingDegree(gfevent.getFillingDegree() + 1);
            wxPostEvent(parent, gfevent);
		}
	}
    if(i >= inFileLength) gfevent.setStatus(FINISHED);
	close(inFileHandle);
	close(outFileHandle);
	free(buffer);
	Exit(0);
	return(0);
}

void copyThread::OnExit()
{
    wxPostEvent(parent, gfevent);
}
