#include <stdio.h>
#include <string.h>

#define MAX_ACCOUNT 50000
#define MAX_TIME 30000
int dex = 0;
int time = 0;
typedef struct ACCOUNT{
char id[11];
char password[11];
int defaulttime;
int startime;
struct ACCOUNT *pre;
struct ACCOUNT *next;

}ACCOUNT;
ACCOUNT HashTable[MAX_ACCOUNT];
ACCOUNT HashIndex[MAX_ACCOUNT];
int da[MAX_TIME];
ACCOUNT *getNewNode()
{
return &HashIndex[dex++];
}
void Init(){
time = 0;
for (int i = 0; i < MAX_ACCOUNT + MAX_TIME; i++)
{
HashTable[i].pre = &HashTable[i];
HashTable[i].next = &HashTable[i];
}
for (int i = 0; i < MAX_ACCOUNT + MAX_TIME; i++)
{
da[i] = 0;
}

}
int getNum(char data[11]){
int val = 0;
for (int i = 0; data[i]; i++)
{
if (data[i] >= '0'&&data[i] <= '9')
{
val = val * 36 + data[i] - '0';
}
else if (data[i] >= 'a'&&data[i] <= 'z')
{
val = val * 36 + data[i] - 'a';
}
val = val % MAX_ACCOUNT;
}

return val;

}
void Insert(int key, ACCOUNT *newNode)
{
ACCOUNT *head = &HashTable[key];
newNode->pre = head;
newNode->next = head->next;
head->next = newNode;
newNode->next->pre = newNode;
}
void deleteNode(ACCOUNT *curNode)
{
curNode->next->pre = curNode->pre;
curNode->pre->next = curNode->next;
}
int same(char str1[], char str2[])
{
int i = 0;
for (i = 0; str1[i] && str2[i]; i++)
{
if (str1[i] != str2[i])
return 0;
}
return 1;
}

ACCOUNT * searchNode1(int key, char id[11]){

ACCOUNT * x = HashTable[key].next;
while (x != &HashTable[key] && !same(x->id, id)){
x = x->next;
}
if (x != &HashTable[key])
return x;
else return NULL;
}
void NewAccount(char id[11], char password[11], int defaulttime)
{
ACCOUNT *newNode = getNewNode();
for (int i = 0; id[i]; i++)
{
newNode->id[i] = id[i];
}
for (int i = 0; password[i];i++)
{
newNode->password[i] = password[i];
}
newNode->defaulttime = defaulttime;
newNode->startime = time;
da[time + defaulttime]++;
int val = getNum(id);
//printf("%d ", val);
Insert(val, newNode);
//printf("NewAccount id = %s defaulttime=%d starttime=%d\n", id, defaulttime, newNode->startime);
}
ACCOUNT * searchNode(int key, char count[11], char pass[11]){

ACCOUNT * x = HashTable[key].next;
//printf("%s \n", x->id);
//printf("%s \n", x->password);
//printf("%s \n", count);
//printf("%s \n",pass);
/*while (x != &HashTable[key] && !same(x->password, pass) && !same(x->id, count)){
x = x->next;
}*/
while (x != &HashTable[key])
{
if (x->id, count)
{
if (same(x->password, pass))
{
return x;
}
}
x = x->next;
}

if (x != &HashTable[key])
return x;
else return NULL;
}
void Logout(char id[11])
{
int val = getNum(id);
ACCOUNT *x = searchNode1(val, id);
if (x)
{
da[x->startime + x->defaulttime]--;
deleteNode(x);
}
//printf("Logout id = %s\n", id);
}
void Connect(char id[11], char password[11]){
//printf("Node = %s\n", id);
int val = getNum(id);
ACCOUNT *x = searchNode(val, id, password);
//printf("Node = %s\n", x->id);
if (x!=NULL){
if (x->startime + x->defaulttime >time)
{
da[x->startime + x->defaulttime]--;
x->startime = time;
da[x->startime + x->defaulttime]++;
}

//printf("Connect id = %s\n", id);
}

}
int Tick(){
time++;
//printf("time = %d\n", time);
//printf("%d ", da[23]);
return da[time];
}