using System;

using System.Collections;

 

using MAPI33;

using MAPI33.MapiTypes;

 

namespace MAPITUT

{

  /// <summary>

  /// Tutorial for MAPI33

  /// </summary>

  public class MapiTutorial

  {

    /// <summary>

    /// Starts a IMAPISession

    /// </summary>

    /// <returns></returns>

    public static IMAPISession StartMapiSession()

    {

      Error err;

      IMAPISession session;

 

      //Initialize MAPI interface driver

      err = MAPI.Initialize(null);

 

      //Logon to the MAPI session with the following flags:

      //MAPI.FLAGS.Extended           Use Extended MAPI interface;

      //MAPI.FLAGS.LogonUI      Show a user dialog if additional credentials required

      //MAPI.FLAGS.NoMail       Do not check for new mail etc.

      //MAPI.FLAGS.USEDEFAULT   Try to use the default profile if possible

      //There are several other flags, see the MAPI33.MAPI.FLAGS enumeration for details!

 

      //object o = MAPI.FLAGS.Extended;

 

      //This call initializes a MAPI session without logon credentials...

 

      err = MAPI.LogonEx(IntPtr.Zero, null, null, MAPI.FLAGS.Extended | MAPI.FLAGS.LogonUI | MAPI.FLAGS.NoMail, out session);

      if (err != Error.Success)

      {

        throw new Exception("Error Initializing Session: " + err.ToString());

      }

      return session;                           

    }

 

    public static void CloseMAPISession(IMAPISession session)

    {

      session.Logoff(IntPtr.Zero, 0);

 

      //dispose object

      session.Dispose();

 

      //uninitialize MAPI driver

      MAPI.Uninitialize();

    }

 

    /// <summary>

    /// Gets all available MessageStores for the given session

    /// </summary>

    /// <param name="session"></param>

    /// <returns>Collection with the ENTRYIDs of the stores</returns>

    public static ICollection GetMessageStores(IMAPISession session)

    {

      ArrayList result = new ArrayList();

      Error err;

      Tags[] itags;

      // In Mapi33, the C++ data type SRowSet has been implemented as rectangular array

      MAPI33.MapiTypes.Value[,] rows;

 

      IMAPITable tblMsgStores;

      err = session.GetMsgStoresTable(MAPI33.IMAPISession.FLAGS.Default, out tblMsgStores);

      if (err != Error.Success)

      {

        throw new Exception("Error Getting Message stores: " + err.ToString());

      }

                                  

      //Define cols to read

      itags = new Tags[] {Tags.PR_ENTRYID};

      err = tblMsgStores.SetColumns(itags, IMAPITable.FLAGS.Default);

      if (err != Error.Success)

      {

        throw new Exception("Error setting Colums for Query: " + err.ToString());

      }

 

      // In Mapi33, the C++ data type SRowSet has been implemented as rectangular array

      //MAPI33.MapiTypes.Value[,] rows;

      err = tblMsgStores.QueryRows(int.MaxValue, IMAPITable.FLAGS.Default, out rows);

      if (err != Error.Success)

      {

        throw new Exception("Error while querying MsgStore: " + err.ToString());

      }

      tblMsgStores.Dispose();

 

      for (int i = 0; i < rows.Length; i++)

      {

        if (rows[i,0].GetType() == typeof(MapiBinary))

        {

          //convert the entry and add it to the result-collection

          result.Add(ENTRYID.Create((byte[])((MapiBinary)rows[i,0]).Value));

        }

      }

      return result;

    }

 

    /// <summary>

    /// Trys to open the Message store with BestAccess Permission

    /// Throws an Exception if something fails

    /// </summary>

    /// <param name="session">IMAPISession to work with</param>

    /// <param name="storeId">ENTRYID of the Message store to open</param>

    /// <returns>IMsgStore</returns>

    public static IMsgStore OpenMsgStore(IMAPISession session, ENTRYID storeId)

    {

      IMsgStore result;

      //the first 3 params are very important

      //For Guid parameter you must pass Guid.Empty value. [1]

      //For parameter named as WindowHandle you must pass IntPtr.Zero value.[1]

      //you have to pass MAPI33.IMAPISession.FLAGS.BestAccess to manipulate items

      Error err = session.OpenMsgStore(IntPtr.Zero, storeId, Guid.Empty, MAPI33.IMAPISession.FLAGS.BestAccess, out result);

      if (err != Error.Success)

      {

        throw new Exception("Error opening MsgStore: " + err.ToString());

      }

      return result;

    }

 

 

    /// <summary>

    /// reads the properties from a IMAPIProp object and returns the Value array

    /// </summary>

    /// <param name="mapipropertyobject"></param>

    /// <returns></returns>

    public static ICollection GetMAPIProperties(IMAPIProp mapipropertyobject)

    {

      Error err;

      Tags [] itags;

      Value [] ivals;

      //Get all available properties for the mapipropertyobject

      err = mapipropertyobject.GetPropList(MAPI33.IMAPIProp.FLAGS.Default, out itags);

      if (err != Error.Success)

      {

        throw new Exception("Error getting Propertylist: " + err.ToString());

      }

 

      //Read the properties of the object

      //itags = new Tags[]{Tags.PR_SUBJECT, Tags.PR_SENDER_NAME}; //to read only Subject and SenderName property

      err = mapipropertyobject.GetProps(itags, MAPI33.IMAPIProp.FLAGS.Default, out ivals);

      if (err != Error.Success)

      {

        throw new Exception("Error getting Properties: " + err.ToString());

      }

 

      //Value contains 3 important things:

      //PropertyTag -> which MAPIProperty? PR_SENDER, PR_ENTRY_ID...

      //Type -> PT_STRING

      //Value -> the value of the property 

      return ivals; //In C# Arrays are "compatible" to the ICollection interface

    }

 

    public static ENTRYID GetRootFolder(IMsgStore store)

    {

      Error err;

      //The PR_IPM_SUBTREE_ENTRYID property contains the entry

      //identifier of the root of the interpersonal message (IPM)

      //folder subtree in the message store's folder tree.

      Tags[] itags = new Tags[] {Tags.PR_IPM_SUBTREE_ENTRYID};

      Value[] ivals;// = new Value[] {new MapiBinary(Tags.PR_IPM_SUBTREE_ENTRYID, new byte[0])};

 

      err = store.GetProps(itags, IMAPIProp.FLAGS.Default, out ivals);

      if (err != Error.Success)

      {

        throw new Exception("Error getting Properties of Store: " + err.ToString());

      }

 

      //Create a new ENTRYID with the value we've read

      //Creation of ENTRYID changes sometimes!!

      ENTRYID rootFldEID = null;//new ENTRYID();

      //we wanted one Tag => we got one Value

      //it contains the ENTRYID of the RootFolder

      rootFldEID = ENTRYID.Create((byte[])((MapiBinary)ivals[0]).Value);

      return rootFldEID;

    }

 

    public static ICollection GetFolders(IMsgStore store)

    {

      return null;

    }

  }

}