/*
**  $VER: Api_Example.c 01.00 (18.12.95)
**
**  © 1995 Jörg Krause
**
**  PROGRAMNAME:
**      Api_Example.c
**
**  FUNCTION:
**      Example Programm which explains how to use Adress-Books Api.
**      Remember that the returned Address list is READ-ONLY. Don't
**      try to change it. I'm not responsible for any data lost or
**      system crashes.
**
**  $HISTORY:
**
**   18.12.95 : 01.00 : initial release
*/

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

#include <exec/types.h>
#include <exec/memory.h>

#include <utility/tagitem.h>

#include <proto/exec.h>


#include "ABook_Api.h"             /* The API includes */

struct MsgPort    *ServerPort;     /* Address-Book's Message Port */
struct MsgPort    *ReplyPort;      /* Our ReplyPort */

struct List       *Addresslist;    /* The Addresslist returned by the Server */



/* This function may be used to send an API message to the server safely
**
** Input: ULONG type
**
**  - AB_Get_Addresses     Obtain a copy of the actual database. You'll get a
**                         pointer to the Addresslist in the replymessage.
**
**  - AB_Dispose           If you are ready with using the address list. Send the
**                         server this command to dipose the copy of your database
**
*/

struct ApiMessage * SendMessage(ULONG Type)
{
    struct MsgPort *APIPort;
    struct ApiMessage *ApiMsg=0;

    /* Allocate the message */
    if ((ApiMsg=AllocVec(sizeof(struct ApiMessage), MEMF_PUBLIC | MEMF_CLEAR)))
    {
        /* Fill in the seperate fields... */

        ApiMsg->Message.mn_Node.ln_Type = NT_MESSAGE;
        ApiMsg->Message.mn_Length       = sizeof(struct ApiMessage);
        ApiMsg->Message.mn_ReplyPort    = ReplyPort;
        ApiMsg->type                    = Type;
        ApiMsg->rc                      = 0;
        ApiMsg->AddressList             = 0;

        /* PutMessageSafely... */

        Forbid();

        APIPort=FindPort("ABSERVER");

        if (APIPort)
            PutMsg(APIPort,(struct Message *)ApiMsg);

        Permit();

        /* Wait for the answer */

        WaitPort( ReplyPort );

        /* Get the replymessage */

        ApiMsg=(struct ApiMessage *)GetMsg(ReplyPort);

    }

    /* And return the result */
    return (ApiMsg);

}

/* The Complete API example
**
** This routine sends an "AB_Get_Addresses" to the server to get a
** copy of the database and then it writes the contents to stdout.
** After that it sends an "AB_Dipose" to the server to disconnect
** this prg and get back all of the used memory....
*/

int main(int argc, char *argv[])
{
    struct ApiMessage *ReplyMessage;

    Forbid();
    if ((ServerPort=FindPort("ABSERVER")))
    {
        Permit();


        if ((ReplyPort=CreateMsgPort()))
        {
            /* Obtain a copy of the database */
            if((ReplyMessage=SendMessage(AB_Get_Addresses)))
            {
                if (!ReplyMessage->rc)
                {
                    struct data *node;

                    /* All goes well and we have a copy of the database */

                    /* Store the Listpointer */
                    Addresslist=ReplyMessage->AddressList;

                    /*Dispose the Replymessage */
                    FreeVec(ReplyMessage);

                    /* Print the contents */
                    node=(struct data *)Addresslist->lh_Head;

                    while (node->node.ln_Succ)
                    {

                        if (node->last)
                            printf("Name: %s ",node->last);

                        if (node->first)
                            printf(", %s\n",   node->first);
                        else
                            printf("\n");

                        if (node->address.lh_Head!=NULL)
                        {
                            struct Address *addrnode;

                            addrnode=(struct Address *)node->address.lh_Head;
                            while (addrnode->addrnode.ln_Succ)
                            {
                                if (addrnode->description)
                                    printf("Address: %s\n",addrnode->description);

                                if (addrnode->Phone.lh_Head)
                                {
                                    struct MList *phonenode;

                                    phonenode=(struct MList *) addrnode->Phone.lh_Head;
                                    while ( phonenode->listnode.ln_Succ)
                                    {
                                        if (phonenode->number)
                                            printf("Number: %s ",phonenode->number);
                                        if (phonenode->description)
                                        {
                                            printf("(%s)\n",phonenode->description);
                                        }
                                        else
                                        {
                                            printf("\n");
                                        }
                                        phonenode=(struct MList *)phonenode->listnode.ln_Succ;
                                    }
                                }
                                addrnode=(struct Address *)addrnode->addrnode.ln_Succ;
                            }
                        }

                        if (node->Email.lh_Head!=NULL)
                        {
                            struct MList *emailnode;

                            emailnode=(struct MList *)node->Email.lh_Head;
                            while (emailnode->listnode.ln_Succ)
                            {
                                if (emailnode->number)
                                    printf("E-mail: %s ",emailnode->number);
                                if (emailnode->description)
                                {
                                    printf("(%s)\n",emailnode->description);
                                }
                                else
                                {
                                    printf("\n");
                                }
                                emailnode=(struct MList *)emailnode->listnode.ln_Succ;
                            }
                        }

                        node=(struct data *)node->node.ln_Succ;
                    }

                    /* Dipose the copy */
                    if ((ReplyMessage=SendMessage(AB_Dispose)))
                    {
                        if (ReplyMessage->rc)
                        {
                            printf("Oops, something goes wrong :(\n");
                        }
                        FreeVec(ReplyMessage);
                    }
                    else
                    {
                        printf("Couldn't dispose the database...\n");
                    }
                }
                else
                {
                    printf("Hmpf, something goes wrong\n");
                }
            }
            else
            {
                printf("Couldn't send message to the Server!\n");
            }

            while (ReplyMessage=(struct ApiMessage *)GetMsg(ReplyPort))
            {
                ReplyMsg((struct Message *)ReplyMessage);
            }

            DeleteMsgPort(ReplyPort);
        }
        else
        {
            printf("Failed to create the Replyport\n");
            return(10);
        }
    }
    else
    {
        Permit();
        printf("The API-Port is not available. Start the ABook-Server to use it!\n");
        return(10);
    }

}


