/**
 * Erstellet einen Socket der horcht
 * @param Der jeweilige Socketdiskriptor 
 * @param Fehlercode
 * @return Der Rückgabewert ist ein Integer und gibt den Socket Deskriptor an
 */ 
int openListenSocket(int lsd,int error){
	 int result = opensocket(SOCK_STREAM, &error);
   	 if(result == API_ERROR){
    	printf("\r\nTCP Echoserver, Open socket failed %d",error);
      	shutDownServer(lsd,error);
   		}//if(result == API_ERROR)
   	 return result;
	}//openListenSocket()
/**
 * Startet die erfoderlichen Sub Socketserver um weiter Clients zu verbinden
 * @param Horchende Socketdeskripto, erforderlich für shitDownServer()
 * @param Fehlercode 
 */
void initSubServerTask(int lsd, int error){
	 for(int i=0;i<MAX_SERVER;i++){
     	int result = RTX_Create_Task(&EchoServer[i].taskID , EchoServer[i].taskdefblock);
     	if(result!=0){
       		printf("\r\nTCP Echoserver Creating task %d failed, err: %d -> exit program\r\n",i,result);
       		shutDownServer(lsd,error);
     		}//if(result!=0)
   	 	}//for(int i=0;i<MAX_SERVER;i++)
	}//initSubServerTask()
/**
 * main()
 */
int main()
{
   int lsd = -1;             //listening socketdescriptor
   int asd = -1;             //new socketdescriptor from accept
   int port  = TM_PORT_ECHO; //default port
   int error = 0;
   int result;
   //int i;

   struct sockaddr_in addr;
   struct sockaddr_in claddr;
   char ClientIP[17];
   int  taskrdy = -1;
   
   initServer();
   startDK40Task();
   initSubServerTask(lsd,error);
   RTX_Sleep_Time(100);
   lsd = openListenSocket(lsd,error);

   
   #ifdef TCPSERV_DEBUG
   printf("\r\nTCP Echoserver: Öffnen einen Socket %d",lsd);
   #endif

  /**
   * Setzt den horchenden Socket auf Wiederverwendbar ein
   * @param lsd Den Socketdeskriptor des horchenden Sockets
   * @param error Fehlercode
   * @return (0) für erfolgreich, ungleich (0) für fehler
   */
   result = setreuse(lsd,&error);
   	
   	#ifdef TCPSERV_DEBUG
   	if(result == API_ERROR){
     	printf("\r\nTCP Echoserver: Set reuse failed %d",error);
   	}
   	#endif
   	
	addr.sin_family =  PF_INET;
	addr.sin_port   =  htons(port); //Konvertierung von Little Endian zu Big Endian
	addr.sin_addr.s_addr =  0L;

   	result = bind(lsd,(struct sockaddr *)&addr,&error);
   	if(result == API_ERROR){
   		printf("\r\nTCP Echoserver, Bind socket failed %d",error);
   		shutDownServer(lsd,error);
	}//(result == API_ERROR)
   

   /*
    * Endlosschleife, horcht und baut Verbindungen auf
    */
   while(1)
   {
      /**
       * listen
       */
      result = listen(lsd, MAX_SERVER, &error);
      if(result == API_ERROR){
        printf("\r\nTCP Echoserver, listen failed %d",error);
        shutDownServer(lsd,error);
      	}//if(result == API_ERROR)

      /**
       * accept , establish a connection
       */
      claddr.sin_family      =  PF_INET;
      claddr.sin_port        =  0;    //clear
      claddr.sin_addr.s_addr =  0L;   //clear

      result = accept(lsd,(struct sockaddr *)&claddr,&error);
      if(result == API_ERROR){
		printf("\r\nTCP Echoserver, accept failed %d",error);
        shutDownServer(lsd,error);
      	}//if(result == API_ERROR)
      
      InetToAscii(&claddr.sin_addr.s_addr,ClientIP);
      
      	#ifdef TCPSERV_DEBUG
      	printf("\r\nTCP Echoserver: Connected with %s , Port %u\r\n",ClientIP,claddr.sin_port);
      	#endif
      
      
      asd = result;
      cnt_connection++;

	       #ifdef SERVER_SHUTDOWN_TEST
    		if(cnt_connection>6L){

	          result =  closesocket(asd,&error);
    	      if(result==API_ERROR){
             	printf("\r\nTCP Echoserver, socket close failed %d",error);
          		}
          	printf("\r\nTCP Echoserver: Shutdown test\r\n");
          	shutDownServer(lsd,error);
      		}//if(cnt_connection>6L)
		   #endif

      /**
       * Suche einer ruhenden Server Task 
       */
      taskrdy =  Get_Free_Server_Task();
      if(taskrdy == -1){  //no sleeping task found
         
         #ifdef TCPSERV_DEBUG
         	printf("\r\nTCPserver: busy, refusing connection with %s , Port %u\r\n",ClientIP,claddr.sin_port);
         #endif
         closesocket(asd, &error);
      }//if(taskrdy == -1)
      else{
      		//insert the socket descriptor
        	EchoServer[taskrdy].sd = asd;
         
	        //and wakeup the sleeping server task
    	    result = RTX_Wakeup(EchoServer[taskrdy].taskID);
         
        	if(result != 0){
           		printf("\r\nTCPserver: wakeup error\r\n");
	           closesocket(asd, &error);
			}//if(result != 0)
        	else{
	        //a task is waked up and serves from now on this connection
    	    }
      }//elseif(taskrdy == -1)  //no sleeping task found
   }//while(1)    //do forever
}
int main(int argc, char *argv[])
{
	int portno,map_id;
	pthread_t receive_connection_thread;
	int receive_t;
	portno=atoi(argv[1]);
	char usertext[10];
	system("setterm -term linux -back green -fore white -bold on -clear");		
	//system("gnome-terminal ");
	//gotoxy(50,50);
	fflush(stdout);	
	clrScreen();
	printCenter("Max No. of Players : ");
	scanf("%d",&max_players);
	clrScreen();
	printCenter("No. Of Automatic Commandos : ");
	scanf("%d",&auto_commando_count);
	clrScreen();	
	printCenter("No.Of Automatic ALiens : ");
	scanf("%d",&auto_alien_count);
	printCenter("   Choose Arena\n");
	printCenter("******************\n");
	printCenter("1 : Forest_War\n");
	printCenter("2 : Nuke_Alien\n");
	printCenter("3 : Mountain_Comm\n");
	printCenter("4 : Mission_Earth\n");
	printCenter("5 : Collapse_CA\n");
	printCenter("Your Choice : ");
	scanf("%d",&map_id);
	clrScreen();	
	initializeGame(map_id);
	serverInit(portno);
	printCenter(" *********The Game Begins Now*******\n");
	printCenter("          Server Established \n");
	printCenter("Waiting For Incomming Connections...\n");
	
	
	//timer();
	//change
	pthread_create(&receive_connection_thread,NULL,receiveIncomingConnections,(void *)&receive_t);
	
	//receiveIncomingConnections();   
	while(1)
	
	{
		printCenter("Press x to Shutdown Server : ");
		scanf("%s",usertext);
		if(strcmp(usertext,"q")==0)
		{
			
			
			system("setterm -default");
	          system("clear");
	   
	           printf("All Connections Terminated\n");
			printf("Server ShutDown\n");
			showAllData(-1);
			shutDownServer();
			//exit(0);
			
		}
		else
		{
			printCenter("Please enter x to quit :\n");
		}
	}
}