#define TOKENS              " ,.;:-_@#!\"\'\\/<>[]{}()\r\n\t*%%&=+-|"

/* converte una query tipo: "123,234,456" in un array di interi */
/* idWord1,idWord2,... */
/* ritorna 0 in caso di errore */
int parseQueries(char* query, unsigned int queryArray[MAXWORDSxQUERY], unsigned int* words)
{
char* pCh = NULL;
int res;

	pCh = strtok (query,",");
    *words = 0;

	if(pCh==NULL || pCh[0]==0)
		return 0;

	while(pCh != NULL)
	{
		res = atoi(pCh);

        /* atoi torna 0 se la stringa non è un numero */
        if(res <= 0)
            return 0;

        queryArray[(*words)] = res;

        (*words)++;

		pCh = strtok (NULL, ",");
	}

return 1;
}

/* converte l'array di parole di una query nel formati ID1,ID2,...,IDn */
char* queryArrayToText(int* queryArray, int elements)
{
MYCSTR text;
int i;
char tmp[16];

    text.myString = NULL;
    text.myString = myCStrCpy(&text,"");
    for(i=0;i < elements;i++)
    {
        if(i==0)
            sprintf(tmp,"%d",queryArray[i]);
        else
            sprintf(tmp,",%d",queryArray[i]);

        text.myString = myCStrCat(&text,tmp);
    }

return text.myString;
}

/* GetWordId
*  if the page exists returns its id
*  else returns 0
*/
int GetWordId(char* word)
{
	char* sqlQuery;
	MYSQL_RES gRes;
	MYSQL_RES** tmpRes=NULL;
	MYSQL_ROW row;
	unsigned int ret;
	
	tmpRes=(MYSQL_RES**)malloc(sizeof(MYSQL_RES));
	
	sqlQuery = malloc(MAXQUERYSIZE);
	
	if(tmpRes==NULL || sqlQuery==NULL)
		MemoryCorruptedHandler("GetWordId");
	
	snprintf_mysql_escaped_sql_statement(&glMysql,sqlQuery,MAXQUERYSIZE-1,"SELECT id FROM %s.wordlist WHERE word='%s' LIMIT 1", glMysqlDB, word);
	
	my_mysql_query_and_store_results(&glMysql, sqlQuery,tmpRes,&gRes);
	
	FREE(sqlQuery);
	
	row = mysql_fetch_row(&gRes);
	
	if(row)
		ret = atoi(row[0]);
	else
		ret = 0;
	
	
	if(*tmpRes)
	{
		mysql_free_result(*tmpRes);
	}
	
	FREE(tmpRes);
	
	
	return ret;
}

/* converte una query tipo: "coded by shen139" in un array di interi */
/* word1,word2,... ==> idWord1,idWord2,... */
/* ritorna 0 in caso di errore */
int parseTextQueries(char* query, unsigned int queryArray[MAXWORDSxQUERY], unsigned int* words)
{
char* pCh = NULL;
int res;

	pCh = strtok (query,TOKENS);
    *words = 0;

	if(pCh==NULL || pCh[0]==0)
		return 0;

	while(pCh != NULL)
	{
		res = GetWordId(pCh);

		printf("\n--%s--%d--\n",pCh,res);
    	/* atoi torna 0 se la stringa non è un numero */
        if(res <= 0)
    	    return 0;

    	queryArray[(*words)] = res;

    	(*words)++;

		pCh = strtok (NULL, TOKENS);
	}

return 1;
}


char* SortRANKSResults(RANKS* results, unsigned int* nResults, int lLimit, int rLimit)
{
int i;
MYCSTR ret;
char elem[20];

    ret.myString=NULL;
    ret.myString = myCStrCpy(&ret,"");

    /* ordina per rank */
    /* ordine crescente perchè poi il limite */
    insertion_sortRanks(results, (*nResults), 1, 1);

    /* se il limite inferiore parte da un elemento non presente nell'array: esce */
    if( (*nResults) < lLimit)
        return ret.myString;

    /* i contenuto frà il limite inferiore e maggiore e il numero massimo di elementi */
    for(i=lLimit; i<rLimit && i < (*nResults) ;i++)
    {
        /* se è l'ultimo elemento dell'array
           o
           l'ultimo elemento del limit
           (non mettere la virgola in fondo)
         */
        if( i == rLimit-1  || i == (*nResults)-1 )
            sprintf(elem,"%d.%d",results[i].page, results[i].rank);
        else
            sprintf(elem,"%d.%d,",results[i].page, results[i].rank);

        ret.myString = myCStrCat(&ret ,elem);
    }

return ret.myString;
}

int CheckUIntArray(unsigned int* a1, unsigned int n1, unsigned int* a2, unsigned int n2)
{
int i;

    if(n1!=n2)
        return 0;

    for(i=0;i<n1;i++)
        if(a1[i]!=a2[i])
            return 0;

return 1;
}

/* unisce(concatena) 2 liste di risultati
   e libera la struttura r1
 */
RANKS* mergeResults(RANKS* r1, unsigned int n1, RANKS* r2, unsigned int n2)
{
RANKS* ret;
int i=0;

    ret = malloc(sizeof(RANKS)*(n1+n2));
    for(i=0;i<n1;i++)
    {
        ret[i].page = r1[i].page;
        ret[i].rank = r1[i].rank;
    }

    for(;(i-n1)<n2;i++)
    {
        ret[i].page = r2[i-n1].page;
        ret[i].rank = r2[i-n1].rank;
    }

    FREE(r1);

return ret;
}

/* limita una lista di risultati al valore voluto
   e libera la vecchia lista dei risultati
   (da chiamare solo in caso di numero elementi < del limite)
 */
RANKS* limitResults(RANKS* r, unsigned int limit)
{
RANKS* ret;
int i=0;

    ret = malloc( sizeof(RANKS)*limit );
    for(i=0;i<limit;i++)
    {
        ret[i].page = r[i].page;
        ret[i].rank = r[i].rank;
    }

    FREE(r);

return ret;
}


