#include <stdio.h>
#include <malloc.h>
#include <oskit/io/blkio.h>
#include <oskit/dev/dev.h>
#include <oskit/dev/linux.h>
#include <oskit/debug.h>
#include <oskit/c/termios.h>
#include <oskit/c/string.h>
#include <oskit/machine/base_vm.h>
#include <oskit/clientos.h>
#include <oskit/startup.h>
#include <oskit/c/unistd.h>	/* _exit */

#include <oskit/diskpart/diskpart.h>


#define blockSize 4096
#define numberOfBlocks 1024
#define fatSize 2
#define blockValid 65000
//fatSize blockides
#define TXTBUFSIZE 1638400
#define ROWLENGTH 80

//NOTE'i muutujad
char TextBuffer[TXTBUFSIZE];
char FilePath[128];
char FileName[128];

oskit_blkio_t *io;
int amount;
int gap;
int block;
int stop;
int fileMode;
char currentBlock[blockSize];
char currentDirLine[16];
unsigned char fat[blockSize*fatSize];
char currentDir[512];

int toInt(unsigned char x, unsigned char y){
	int tulem;
	tulem = (x << 8) + y;
	return tulem;
}
//MEETODID READPHYSICALLY JA WRITEPHYSICALLY TULEB ASENDADA OSKITIST
int readPhysically(int offset, int size){
	int err, amt;

	err = oskit_blkio_read(io, currentBlock, offset, size, &amt);
	if (err) {
		printf("  Read ERROR %08x\n", err);
		return(-1);
	}
	return 1;
}

int writePhysically(int offset, int size, char *buf){
	int err, amt;

	err = oskit_blkio_write(io, buf, offset, size, &amt);
	if (err || amt != size) {
		printf("  Write ERROR %d\n", err);
                return(-1);
   }
	return 1;
}
int readBlock(int block_nr){
	//err = oskit_blkio_read(io, buf, offset, size, &amount);
	if(block_nr >= numberOfBlocks) return -1;
	else return readPhysically((block_nr+fatSize)*blockSize, blockSize);
}

int writeBlock(int block_nr, char* input){
	if(block_nr >= numberOfBlocks) return -1;
	else return writePhysically((block_nr+fatSize)*blockSize, blockSize, input);
}

int readFAT(void){//loe fat buffrisse
	int counter, fatCounter, blockCounter;
	counter = 0;
	fatCounter = 0;
	while(counter < fatSize){
		blockCounter = 0;
		jumpToBlock(counter-fatSize);
		while(blockCounter < blockSize){
			fat[fatCounter] = currentBlock[blockCounter];
			fatCounter++;
			blockCounter++;
		}
		counter++;
	}
}

int flushFAT(void){//kirjuta fat kettale
	char fatBuf[blockSize];
	int counter;
	int counter2;
	int counter3;
	counter3 = 0;
	for(counter = 0; counter < fatSize; counter++){
		for(counter2 = 0; counter2 < blockSize; counter2++){
			fatBuf[counter2] = fat[counter3];
			counter3++;
		}
		writeBlock((counter-fatSize), fatBuf);
	}
}//flushFAT

int flushBlock(void){
	writeBlock(block, currentBlock);
}

int format(int size){//size on blockides
	int counter, counter2;
	char x;
	counter = (0-fatSize);//fat ka nulliks
	printf("FORMAT?\n");
	x = getchar();
	if(x != 'y') return -1;
	while(counter < size){
		readBlock(counter);
		counter2 = 0;
		while(counter2 < blockSize){
			currentBlock[counter2] = 0;
			counter2++;
		}
		writeBlock(counter, currentBlock);
		counter++;
	}
	return 1;
}

int jumpToBlock(int block_nr){
	block = block_nr;
	gap = 0;
	readBlock(block);
	return 1;
}

int getLink(int block_nr){//tagastab currentBlock byte'dest 4094-4095 12 esimest bitti int'na
	int x;
	x = toInt(fat[block_nr*2], fat[(block_nr*2) + 1]);
	return x;
}

unsigned readByte(void){
	unsigned x;
	if(gap >= blockSize){
		if(gap >= (blockSize+1)) abort();//fatal error ;)
		jumpToBlock(getLink(block));
		x = currentBlock[gap];
		gap++;
		return x;
	}
	else{
		x = currentBlock[gap];
		gap++;
		return x;
	}
}
int writeByte(char x){
	int newBlock;
	if(gap >= blockSize){
		if(gap > blockSize) abort();//fatal error ;)
		newBlock = findEmptyBlock();//otsi uus blokk, kust jätkata kirjuamist
		if(newBlock == -1) return -1;//ketas täis
		setLink(block, newBlock);//lingi vanast blokist uude
		flushBlock();//kirjuta vana block kettale
		jumpToBlock(newBlock);//loe uus block buffrisse
		setBlockValid(block);//uus block on ka nyyd kasutusel
		currentBlock[gap] = x;//väärtusta
		gap++;
	}
	else{
		currentBlock[gap] = x;
		gap++;
	}
	return 1;
}
int readDirLine(void){
//eeldatakse, et lugemispea (block && gap) on kohas kus on dir line kirjed
/* 
	[0...12] on file nimi
	[13] isDir (%2==1 isDir, %2==0 notDir)
	[14][15] - blocki nr. kust algab
*/
	int counter;
	counter = 0;
	while(counter < 16){
		currentDirLine[counter] = readByte();
		counter++;
	}
	if(currentDirLine[13] == 0){
		if(gap > 4079) return -1;
		else return 0;
	}
	return 1;
}

int printDirLine(char* dirLine){
	int counter;
	for(counter = 0;counter < 13;counter++){
		if(dirLine[counter!=0]) printf("%c",dirLine[counter]);
	}
	if(currentDirLine[13] % 2 != 0){
		printf(" [dir]");
	}
	printf("\n");
	return 1;
}

int listFiles(void){//eeldatakse, et lugemispea on blokis kus on dir line kirjed
	int x;
	gap = 0;//hakka bloki algusest
	x = readDirLine();
	while(x != -1){
		if(x != 0) printDirLine(currentDirLine);
		x = readDirLine();
	}
	return 1;
}
int findEmptyRow(void){
	int counter, byteCounter;
	byteCounter = 0;
	for(counter = 0; counter < blockSize; counter+=16){
		if(currentBlock[counter+13] == 0) return counter;
	}
	return -1;//rohkem faile siia folderisse ei mahu
}

int mkFile(char* sisend, int isDir){//U U S
//eeldus on, et currentBlock oleks dir
	char s[16];
	int counter, newBlock, x, y, to;
	strcpy(s,sisend);
	x = findFileRow(s);
	if(x != -1){
		printf("Fail eksisteerib!\n");
		return -1;
	}
	gap = findEmptyRow();
	if(gap < 0){//ei mahu rohkem faile
		gap = 0;
		return -1;
	}
	to = strlen(s);
	for(counter = 0; counter < 13; counter++){
		if(counter >= to) writeByte(0);
		else writeByte(s[counter]);
		
	}
	newBlock = findEmptyBlock();
	if(newBlock == -1) return -1;//ketas täis
	x = newBlock >> 8;
	y = newBlock & 0377;
	writeByte(isDir);
	writeByte(x);
	writeByte(y);
	setBlockValid(newBlock);
	flushBlock();//et ikka kirja läheks
	jumpToBlock(newBlock);
	writeByte(0);//et block oleks tyhi
	goToCurrentDir();
	return 1;
}

int getFileStartBlock(char* s){
//otsib currentBlock'ist kas on selle nimega fail
//kui on siis tagastab bloki numbri, kus fail algab
	int result, x;
	gap = 0;//hakka algusest
	x = readDirLine();
	while(x != -1){
		result = strcmp(currentDirLine, s);
		if(result == 0){
			x = toInt(currentDirLine[14], currentDirLine[15]);
			return x;
		}
		x = readDirLine();
	}
	return -1;
}
int goToDir(char* sisend){//U U S
	int i, x;
	char * token;
	char * const seps = "/";
	char s[512];
	flushBlock();
	strcpy(s,sisend);
	jumpToBlock(0);
	token = strtok(s, seps);
	while( token != NULL ){
		i = getFileStartBlock(token);
		if((currentDirLine[13] % 2) == 0 || i == -1){
			if(i == -1) printf("Sellist faili ei ole\n");
			else printf("Ei ole diri\n");
			return -1;
		}
		if(i == -1) return 1;
		jumpToBlock(i);
		token = strtok(NULL, seps);
	}//while toke != NULL
	return 1;
}
int goToCurrentDir(void){
	int x;
	char tmpDir[512];
	strcpy(tmpDir,currentDir);
	flushBlock();
	if(strlen(currentDir) < 2){
		jumpToBlock(0);
		return 1;
	}
	x = goToDir(tmpDir);
	if(x == -1){//kui ei saa currentDir'i minna, siis mine juure peale
		currentDir[0] = '/';
		currentDir[1] = 0;
		jumpToBlock(0);
	}
	else return x;
}
int updateCurrentDir(char * s, int juurde){
	int len, len2, counter, i, stop;
	char tmpCurDir[512];
	if(juurde == 1){
		len = strlen(currentDir);
		len2 = strlen(s);
		i = 0;
		for(counter = len; counter < (len + len2); counter++){
			currentDir[counter] = s[i];
			i++;
		}//lisa juurde
		currentDir[counter] = '/';
	}
	else{
		strcpy(tmpCurDir,currentDir);
		len = strlen(tmpCurDir);
		if(len < 2) return -1;
		stop = 1;
		for(counter = len-2; counter  > 0 && stop == 1; counter--){
			if(tmpCurDir[counter] == '/') stop = -1;
		}//counter > 0
		for(counter++; counter <= len; counter++){
			currentDir[counter] = 0;
		}//counter < len
		if(!(strlen(currentDir) < 2)) currentDir[strlen(currentDir)] = '/';
	}//cd ..
	return 1;
}
int changeDir(char* s){
	int dirBlock, i;
	i = strncmp(s,"..",2);
	if(i == 0){
		updateCurrentDir("..",-1);
		goToCurrentDir();
		return 1;
	}//kui cd ..
	i = strcmp(s,"/");
	if(i == 0){//mine kodu kataloogi
		currentDir[0] = '/';
		currentDir[1] = 0;
		jumpToBlock(0);
		return 1;
	}
	else{
		i = goToCurrentDir();
		dirBlock = getFileStartBlock(s);
		if(dirBlock != -1 && ((currentDirLine[13] % 2) != 0)){//on dir kuhu minna?
			jumpToBlock(dirBlock);
			updateCurrentDir(s,1);
			return 1;
		}
		goToCurrentDir();
	}//tavaline changeDir
	return -1;
}
int findEmptyBlock(){//otsi block mis on invalid
	int counter, x;
	for(counter = 0; counter < (numberOfBlocks-fatSize); counter++){
		if(!(isBlockValid(counter) == 1)) return counter;
	}
	return (-1);
}
int isBlockValid(int blockNumber){//kontrolli FAT'ist kas block on valid
	int x;
	x = toInt(fat[blockNumber*2], fat[(blockNumber*2) + 1]);
	if(x == 0) return -1;//ei ole valid
	else return 1;//on valid
}
int setBlockInvalid(int blockNumber){
	setLink(blockNumber, 0);
}
int setBlockValid(int blockNumber){
	int z, x, y, value;
	z = toInt(fat[blockNumber*2], fat[(blockNumber*2) + 1]);
	if(blockNumber >= numberOfBlocks-fatSize) return (-1);//liiga suur block
	if(z != 0) return (0);//on juba valid
	value = blockValid;
	x = value >> 8;
	y = value & 0377;
	fat[blockNumber*2] = x;
	fat[(blockNumber*2) + 1] =  y;
	flushFAT();
	return 1;
}
int isLinkValid(int blockNumber){
	int link;
	link = toInt(fat[blockNumber*2], fat[(blockNumber*2)+1]);
	if((link == 0 || link == blockValid)) return 0;//ei ole valid
	else return 1;
}
int delLink(int blockNumber){
	int x;
	x = toInt(fat[blockNumber*2], fat[(blockNumber*2) + 1]);
	if(x == 0) return (-1);//ei block ei ole valid
	setLink(blockNumber, blockValid);
	return 1;
}
int setLink(int fromBlock, int toBlock){
	unsigned char x, y;
	if(fromBlock >= (numberOfBlocks-fatSize)) return (-1);
	//sest siis asuksid blockid fs'i piirkonnas väljas
	x = toBlock >> 8;
	y = toBlock & 0377;
	fat[fromBlock*2] = x;
	fat[(fromBlock*2) + 1] = y;
	flushFAT();
	return 1;
}
int findFileRow(char* f){
	int y, counter, result;
	char file[16];
	strcpy(file, f);
	gap = 0;//blocki algusest
	y = readDirLine();
	for(counter = 0; y != -1 && counter < 256; counter++){
		result = strncmp(currentDirLine, file, strlen(file));
		if(result == 0){//leidsin rea
			return counter*16;
		}
		y = readDirLine();
	}//while y
	return -1;//ei leidnud
}
int deleteFile(char* path, char* file){
	int x, y, counter;
	jumpToBlock(0);
	x = goToDir(path);
	if (x == -1) return -1;
	x = getFileStartBlock(file);
	y = findFileRow(file);
	if(y == -1) return -1;
	gap = y;
	for(counter = 0; counter < 16; counter++){
		writeByte(0);
	}//kustuta dir'ist kirje
	flushBlock();//et kirja läheks
	counter = 1;
	while(counter == 1){
		y = toInt(fat[x*2], fat[(x*2)+1]);
		if(y == 0 || y == blockValid) counter = -1;
		setBlockInvalid(x);
		x = y;
	}//kustuta file fat'ist
	return 1;
}
int fileOpen(char* p, char* file, char mode){
	//globaalmuutuja fileMode on selleks et keelata vajadusel writeByte();
	//kuid ei ole veel realiseeritud
	int x;
	char path[512];
	strcpy(path,p);
	if(mode == 'r'){//r
		fileMode = 1;//read file
	}else if(mode == 'w'){
		fileMode = 2;//write file
	}else if(mode == 'a'){
		fileMode = 3;//append NB ei ole veel realiseeritud
	}else return -1;
	x = goToDir(path);
	if(x == -1) return -1;
	if(mode == 'w'){
		x = deleteFile(path, file);
		x = goToDir(path);
		mkFile(file, 2);//mitte dir
	}
	x = getFileStartBlock(file);
	if(x == -1) return -1;
	jumpToBlock(x);
	return 1;
}
int fileClose(){
	fileMode = 0;
	writeByte(0);
	flushBlock();
	goToCurrentDir();
	return 1;
}
int cp(char* inputFile, char* outputFile){
	char tempBlock[blockSize];
	char inputPath[256];
	char outputPath[256];
	char inputF[256];
	char outputF[256];
	int inputBlock, outputBlock, counter, counter2, len, stop, newblock, liida;
	//KRIJUTA INPUTFILE JA OUTPUTFILE LAHTI
	len = strlen(inputFile);
	stop = 1;
	for(counter = len-2; counter  > 0 && stop == 1; counter--){
		if(inputFile[counter] == '/'){
			stop = -1;
		}
	}//otsi koht
	for(counter2 = 0; counter2 <= counter; counter2++){
		inputPath[counter2] = inputFile[counter2];
	}//väärtusta inputPath
	inputPath[counter2] = 0;//et string ikke lõpeks ära ka
	if(counter == 0) liida = 1;
	else liida = 2;
	for(counter2 = 0; counter2 < len-counter;counter2++){
		inputF[counter2] = inputFile[counter2+counter+liida];
	}//väärtusta inputF
	len = strlen(outputFile);
	stop = 1;
	for(counter = len-2; counter  > 0 && stop == 1; counter--){
		if(outputFile[counter] == '/'){
			stop = -1;
		}
	}//otsi koht
	counter2 = 0;
	for(counter2 = 0; counter2 <= counter; counter2++){
		outputPath[counter2] = outputFile[counter2];
	}//väärtusta outputPath
	outputPath[counter2] = 0;//et string ikke lõpeks ära ka
	if(counter == 0) liida = 1;
	else liida = 2;
	for(counter2 = 0; counter2 < len-counter;counter2++){
		outputF[counter2] = outputFile[counter2+counter+liida];
	}//väärtusta outputF
	//KRIJUTA INPUTFILE JA OUTPUTFILE LAHTI
	
	stop = goToDir(inputPath);
	if(stop == -1) return -1;
	inputBlock = getFileStartBlock(inputF);
	if(inputBlock == -1) return -1;
	stop = goToDir(outputPath);
	if(stop == -1) return -1;
	stop = mkFile(outputF,2);//%2 == 0 => FAIL, MITTE DIR
	if(stop == -1) return -1;
	outputBlock = getFileStartBlock(outputF);
	readBlock(inputBlock);
	counter = 0;
	for(stop = 1; stop == 1;counter++){
		writeBlock(outputBlock, currentBlock);
		setBlockValid(outputBlock);
		inputBlock = getLink(inputBlock);
		if(inputBlock < 1 || inputBlock == blockValid || counter > 100){
			stop = -1;
			setLink(outputBlock, blockValid);
		}else{//lingi ja võta uus block
			newblock = findEmptyBlock();
			setLink(outputBlock, newblock);
			outputBlock = newblock;
			readBlock(inputBlock);
		}//on järgmine block olemas failil
	}//for stop == 1
	readBlock(block);//et buffris oleks oige block
	goToCurrentDir();
	return 1;
}//copy file to file
int rm(char *s){
    char tempDir[512];
    char tempFile[14];
    int x;
    strcpy(tempDir,currentDir);
    strcpy(tempFile,s);
    if(goToCurrentDir() == -1) return -1;
    x = findFileRow(tempFile);
    if(x < 0) return -1;
    if(currentBlock[x + 13] % 2 != 0){
        printf("%s on kataloog\n",s);
        return -1;//s on dir
    }
    return deleteFile(tempDir,s);
}
int rmDir(char *s){
	char tempDir[512];
	char tempFile[14];
	int x, counter, stop, i;
	strcpy(tempDir,currentDir);
	strcpy(tempFile,s);
	if(goToCurrentDir() == -1) return -1;
	x = findFileRow(tempFile);
	if(x < 0) return -1;
	if(currentBlock[x + 13] % 2 == 0){
		printf("%s ei ole kataloog\n",s);
			return -1;//s ei ole dir
	}
	changeDir(s);
	for(counter = 0; counter < 256; counter++){
		x = readDirLine();
		if(x == 1){
			printf("%s ei ole tyhi kataloog\n",s);
			return -1;
		}//if
		if(x == -1) counter = 300;
	}//for
	changeDir("..");
	x = deleteFile(tempDir,s);
	goToCurrentDir();
	return x;
}
int cd(char * s){
	return changeDir(s);
}
int mkdir(char * s){
	int x;
	x = mkDir(s);
	goToCurrentDir();
	return x;
}
int pwd(){
	printf("PWD: %s\n",currentDir);
	return 1;
}
int mv(char* file, char* to){//parem mv
	int x, counter, len;
	char tmpFile[16];
	char tmpTo[512];
	char fileRow[16];
	len = strlen(file);
	strcpy(tmpFile, file);
	strcpy(tmpTo, to);
	x = goToDir(tmpTo);
	if(x == -1){
		printf("Siht kataloogi ei eksisteeri");
		return -1;//ei ole path'i
	}
	goToCurrentDir();
	x = findFileRow(tmpFile);
	if(x == -1){
		printf("Faili ei eksisteeri");
		return -1;//ei ole path'i
	}
	gap = x;//et hakkaks õigest kohast
	for(counter = 0; counter < 16; counter++){//kustuta rida
		fileRow[counter] = currentBlock[gap];//kopeeri rida
		writeByte(0);//ja kustuta
	}//for counter < 16
	goToDir(tmpTo);
	gap = findEmptyRow();
	if(gap == -1){
		gap = 0;
		printf("Kataloogi ei mahu rohkem faile\n");
		return -1;//ei mahu sinna faile enam
	}
	for(counter = 0; counter < 16; counter++){
		writeByte(fileRow[counter]);
	}//kirjuta uude kohta
	goToCurrentDir();
	return 1;
}//mv

/*int mv(char* file,char* to){//copy rm'iga on kulukas
	int x;
	char	tmp1[512];
	char	tmp2[512];
	strcpy(tmp1,currentDir);
	strcat(tmp1,file);
	strcpy(tmp2,to);
	strcat(tmp2,file);
	x = cp(tmp1, tmp2);
	if(x == -1) return -1;
	goToCurrentDir();
	return rm(file);
}*/

int more(char* s){
	int counter, counter2, stop;
	char taht;
	stop = 1;
	fileOpen(currentDir, s,'r');
	while(stop == 1){
		taht = readByte();
		if(taht == 0){
			printf("\n--Faili l6pp--\n");
			fileClose();
			return 1;
		}
		if(taht == '\n'){
			counter2 = 0;
			counter++;
		} else counter2++;
		if(counter2 > 80){
			counter2 = 0;
			counter++;
		}
		if(counter >= 22){
			printf("\n--Vajuta suvalist klahvi j2tkamiseks--\n");
			getchar();
			counter = 0;
		}//
		putchar(taht);
	}
	fileClose();
	putchar('\n');
	return 1;
}

int printFAT(){
	int counter;
	char tmpChar;
	for(counter = 0; counter < numberOfBlocks; counter++){
		if(counter %20 == 0){
			printf("\n--J2tkamiseks vajuta \"c\"--\n");
			tmpChar = getchar();
			if(tmpChar != 'c') return 1;
		}
		printf(" %d :: %d\n", counter, toInt(fat[counter*2], fat[(counter*2) + 1]));
	}//for counter
	return 1;
}
int ls(){
	int x;
	x = goToCurrentDir();
	if(x == -1) return -1;
	else listFiles();
	return 1;
}
//SHELL MEETODID
int noslogo(void){
	printf("\n                  ____    _  ___   ____\n                 /    \\  | |/   \\ /   _|\n                 |     \\ | |  ^  |\\  \\\n                 |  ^   \\| |  || | \\  \\\n                 |  ||     |  || |__\\  \\\n                 |__||____/ \\___/ |____/\n\n                     Not Operating System\n\t     Using NOFS16\n\n");
	return 1;
}//noslogo

int fu(char* s){
	int x;
	printf("\n Dear %s\n", s);
	printf("\n                           ____\n                          / __ \\\n                          ||__| |\n");
	for(x = 0; x < 7; x++){
		printf("                          |     |\n");
	}
	printf("               ____  ____ |     | ____  ____\n              /    \\/    \\|     |/    \\/    \\\n");
	for(x = 0; x < 4;x++){
		printf("             |     |      |     |      |     |\n");
	}
	printf("             \\                              /\n              \\           FUCK YOU         /\n               \\__________________________/\n\n");
	return 1;
}//UNOFFICIAL

int mkDir(char* s){// U U S
	int x;
	char tmpSisend[16];
	strcpy(tmpSisend,s);
	x = mkFile(s, 1);
	if(x == -1) return -1;
	goToCurrentDir();
	x = changeDir(tmpSisend);
	for(x = 0; x < blockSize-1; x++){
		writeByte(0);//kirjuta folderi sisu 0'ks
	}
	flushBlock();
	changeDir("..");
	return 1;
}

/*	SHELL TSYKKEL
		*****
*/

int help(void){
    noslogo();
    printf("SHELLI K2SUD:");
    printf("\n---------------------\n");
    printf("* cp v6i kopeeri: atribuute 2\n");
    printf("  **cp molemad atribuudid on faili full pathid\n");
    printf("* cd v6i vk: atribuute 1\n");
    printf("  ** cd atribuut on folderinimi (mitte full path)\n");
    printf("* mkdir v6i teekataloog: atribuute 1\n");
    printf("* rmdir v6i kk: atribuute 1\n");
    printf("  ** mkdir ja rmdir atr on folderinimi (mitte full path)\n");
    printf("* ls v6i ks: atribuute 0\n");
    printf("* note v6i kriba: atribuute 0\n");
    printf("* mv v6i liiguta: atribuute 2\n");
    printf("  ** mv 1. atr on failinimi; 2. atr on path (kuhu liigutada)\n");
    printf("* rm v6i kustuta: atribuute 1\n");
    printf("* pwd v6i jk: atribuute 0\n");
    printf("* more v6i veel: atribuute 1\n");
    printf("* reboot v6i rebu: atribuute 0\n");
    printf("\n");
    return 1;
}//help


int implement(char *cmd, int jrkr){//interpreteeri kask

	int i, x, count;
	char * token;
	char * const seps = " ";
	char a[4][256];
	char s[512];
	for(count = 0;count < 4;count++){
		a[count][0] = 0;
	}
	strcpy(s,cmd);
	token = strtok(s, seps);
	count = 0;
	while( token != NULL ){
		strcpy(a[count],token);
		count++;
		token = strtok(NULL, seps);
	}//while toke != NULL

  if (strcmp(a[0],"cp")==0 || strcmp(a[0],"kopeeri")==0){
	  if (count!=3){
   	return -1;
	  }
	  return(cp(a[1],a[2]));
  }
  else if (strcmp(a[0],"mkdir")==0 || strcmp(a[0],"teekataloog")==0){
     if (count!=2){
   	  return -1;
	  }
	  return (mkdir(a[1]));
  }

  else if (strcmp(a[0],"mv")==0 || strcmp(a[0],"liiguta")==0){
     if (count!=3){
        return -1;
     }
     return(mv(a[1],a[2]));
  }
  else if (strcmp(a[0],"more")==0 || strcmp(a[0],"veel")==0){
     if (count!=2){
        return -1;
     }
     return(more(a[1]));
  }
  else if (strcmp(a[0],"rm")==0 || strcmp(a[0],"kustuta")==0){
     if (count!=2){
        return -1;
     }
     return(rm(a[1]));
  }


  else if (strcmp(a[0],"rmdir")==0 || strcmp(a[0],"kk")==0){
     if (count!=2){
        return -1;
     }
     return(rmDir(a[1]));
  }
  else if (strcmp(a[0],"fat")==0 || strcmp(a[0],"FAT")==0){
     if (count!=1){
        return -1;
     }
     return(printFAT());
  }
   else if (strcmp(a[0],"help")==0 || strcmp(a[0],"abi")==0){
     if (count!=1){
        return -1;
     }
     return(help());
  }

  else if (strcmp(a[0],"pwd")==0 || strcmp(a[0],"jk")==0){
     if (count!=1){
        return -1;
     }
     return(pwd());
  }


  else if (strcmp(a[0],"note")==0 || strcmp(a[0],"kriba")==0){
     if (count!=1){
        return -1;
     }
     return(note());
  }
  else if (strcmp(a[0],"reboot")==0 || strcmp(a[0],"rebu")==0){
     if (count!=1){
        return -1;
     }
	  stop = -1;
     return 1;
  }
  else if (strcmp(a[0],"fu")==0 || strcmp(a[0],"mp")==0){
     if (count!=2){
        return -1;
     }
     return(fu(a[1]));
  }
  else if (strcmp(a[0],"nos")==0 || strcmp(a[0],"logo")==0){
     if (count!=1){
        return -1;
     }
     return(noslogo());
  }
  else if (strcmp(a[0],"ls")==0 || strcmp(a[0],"ks")==0){
     if (count!=1){
        return -1;
     }
     return(ls());
  }

  else if (strcmp(a[0],"cd")==0 || strcmp(a[0],"vahetakataloog")==0 || strcmp(a[0],"vk")==0){
     if (count!=2){
        return -1;
     }
     return(cd(a[1]));
  }
  else return -1;
}/*implement l6pp*/


/*		*****
	SHELL TSYKKEL
*/


/*N O T E*/
/*N O T E - not operating text editor*/
void ClearScreen()
{
	int i;
	for (i = 0; i < 24; i++)
		printf("\n");
};

void ClearPrevChar()
{
	putchar('\b');
	putchar(' ');
	putchar('\b');
};

int GetLastRowLength(char* text)
{
	int i = 1;
	int c = 0;
	int textlength = strlen(text);
	while ((c != '\n') && (i <= (textlength+1)))
	{
		c = TextBuffer[textlength-i];
		i++;
	}
	return ((i-1+ROWLENGTH) % ROWLENGTH);
};

// Loeb sisendi massiivi dest, alustades massiivi baidist, mida näitab offset.
// endchar on sümbol, mil
char* ReadInput(char* dest, int offset, char endchar)
{
	int c = 0;

	while (c != endchar)
	{
		c = getchar();
		if (c == '\b')
		{
			if (offset > 0)
			{
				offset = offset - 1;
				if (dest[offset] == '\n')
				{
					dest[offset] = 0;
					int rowlength = GetLastRowLength(TextBuffer);
					
					int i;
					for (i = 0; i < (ROWLENGTH-rowlength); i++)
						putchar('\b');
				}
				dest[offset] = 0;
				ClearPrevChar();
			}
		}
		else
		{
			if (c == endchar)
			{
			}
			else
			{
				if (c == '\r')
				{
					dest[offset] = '\n';
					offset = offset + 1;
					putchar('\n');
				}
				else
				{
					dest[offset] = c;
					offset = offset + 1;
					putchar(c);
				}
			}
		}
	};

	printf("\n");
};

int note()
{
	int offset = 0;
	int c = 1;
	int i;

	ClearScreen();

	printf("NOTE v0.1 Beta\n");
	printf("Faili asukoht: ");
	ReadInput(FilePath, 0, '\r');
	
	if(goToDir(FilePath) == -1){
		printf("Kataloogi pole olemas\n");
		return -1;
	}

	for(i = 0; i < 128; i++){
		FileName[i] = 0;
	}//kustuta
	
	printf("Faili nimi: ");
	ReadInput(FileName, 0, '\r');

	if(findFileRow(FileName) == -1){
		mkFile(FileName,2);
	}

	if (fileOpen(FilePath, FileName, 'r') == 1)
	{
		ClearScreen();

		c = readByte();
		while ((c != 0) && (offset < TXTBUFSIZE))
		{
			TextBuffer[offset] = c;
			putchar(c);
			c = readByte();
			offset += 1;
		}

		fileClose();
	}

	ReadInput(TextBuffer, offset, 24);

	ClearScreen();

	printf("\nKas soovite faili %s salvestada? (y/n)", FileName);
	c = getchar();
	if (c == 'y')
	{
		fileOpen(FilePath, FileName, 'w');
		int i;
		int TextLength = strlen(TextBuffer);
		for (i = 0; i < TextLength; i++)
		{
			writeByte(TextBuffer[i]);
		}
		printf("\nFaili kirjutati %d baiti\n", i);
		fileClose();
	}

	return 1;
}

/*	N O T E
	not operating text editor
*/

int printCmdLine(int i){
	printf("[%d]:%s> ",i,currentDir);
	return 1;
}

int init(void){
	stop = 1;
	format(numberOfBlocks-fatSize);
	currentDir[0] = '/';//root kataloog on /
	readFAT();//loe fat mällu
	jumpToBlock(0);
	setBlockValid(0);
	noslogo();
	return 1;
}
int main(){
	int counter;	
	int y;
	char tmp[512];
	int rc;
	int err = 0;
	char name[10];
	oskit_size_t sec_size;
	oskit_off_t disk_size;
	int n_tests, i, j;
	char* kask;
	int nr,kala,x,ii;

#ifndef KNIT
	oskit_clientos_init();
	start_blk_devices();
#endif
	oskit_dump_devices();
#ifdef  GPROF
	start_fs_bmod();
	start_gprof();
	pause_gprof(0);
#endif
	printf("\nKirjuta ketta nimi: (valjumiseks *v2lja*) : ");
	gets(name);
	if (!strcmp(name, "v2lja"))
		return 1;

	printf("Avan ketast %s...\n", name);
	err = oskit_linux_block_open(name, OSKIT_DEV_OPEN_READ | OSKIT_DEV_OPEN_WRITE, &io);
	if (err) {
		if (err == OSKIT_E_DEV_NOSUCH_DEV)
			printf("Ketast %s ei eksisteeri!\n", name);
		else	
			printf("viga %x ketta avamisel %s\n", 
			       err, name);
	}

	init();

	mkdir("neeger");
	changeDir("neeger");
	mkFile("txtfail",2);//%2 == 0 => fail
	fileOpen(strcpy(tmp,currentDir),"txtfail",'w');
	for(counter = 0; counter < 3000;counter++){
		writeByte('x');
		writeByte('y');
		writeByte('z');
	}
	fileClose();
	changeDir("..");
	kask="";
	x=0;
	counter = 1;
	printf("[%d]:%s> ",counter,currentDir);
	while (stop == 1){
		nr=0;
		gets(kask);
		x = implement(kask, strlen(kask));
		if (x == -1){
			printf("Viga! Kontrolli k2sk yle!\n");
		}
		nr = strlen(kask);
		if (nr!= -1){
			for(ii=0; ii<nr; ii++){
				kask[ii]=0;
			}//for ii
		}//nr != -1
		printf("");
		counter++;
		printCmdLine(counter);
    }//while stop == 1
	flushBlock();//buffrid tyhjaks
	flushFAT();//buffrid tyhjaks
	oskit_blkio_release(io);
	return 1;
}
