Overview
========

This document exclusively concerns configuring your development environment to
use Zumero in a Windows Desktop app.  For information about the actual usage of
Zumero's sync functionality, consult the documentation available both in the
ZSS Client SDK under `docs` and on the web at the
[Zumero Dev Center][zumerodev].

[zumerodev]: http://zumero.com/dev-center/


Quick Start
===========

If you've downloaded the ZSS Client SDK and want to dive straight into code,
then follow the steps outlined in this section.  If you're looking for more
information about how to integrate Zumero into your app, skip down to the next
section.

1) Copy `sqlite3.c` and `sqlite3.h` from the SQLite source into the folder
   `windows\samples\sqlite3`.  The samples will build against that version of
   SQLite.
2) Open `samples.sln` in the `samples` folder, then build, run, and explore the
   code.  See the README in the `samples` folder for more info about them.
   That README is also accessible directly from Visual Studio as a solution
   item while `samples.sln` is open.


Zumero Usage
============

There are two different ways to use Zumero in your Desktop application:

1. Zumero Static Library (for native apps)
2. Zumero .NET Assembly (for .NET apps)

Each option has its own section of detailed information below.


Zumero Static Library (for Desktop)
===================================

The Zumero Static Library is a native library/header that contains only Zumero
functionality.  It is the lowest possible level that you can interface with
Zumero.  The other options are ultimately wrappers around this static library.

The Zumero Static Library has the following requirements of its caller:

1. It must be built with Visual Studio 2012.
2. It must link with SQLite (version 3.7.17 or newer is recommended).

## Project Configuration

You'll need to manually modify three compiler/linker settings of your project:
the include path, the lib path, and the linker inputs.  The include path and
lib path must be updated to contain Zumero's files, and the linker inputs need
to be updated to include `zumero_client_api.lib` and its dependencies.

The Zumero Static Library has two dependencies (other than SQLite): zlib and
WinInet.  Anything that links with `zumero_client_api.lib` must also link with
those dependencies.

* WinInet is a Windows library and comes with Visual Studio, so to link with it
  you merely need to add `wininet.lib` to the linker's list of libraries.
* Zlib is a free open source compression library.  Pre-built zlib libraries are
  included in the ZSS Client SDK right next to the corresponding
  `zumero_client_api.lib`, so again you merely need to add `zlib.lib` to the
  linker's list of libraries.  However, you could also download the zlib source
  from [its web site][zlibdl] and link to your own build of it if you wish.

[zlibdl]: http://www.zlib.net

The easiest way to configure all of this in Visual Studio is as follows:

1. Right-click your project and choose `Properties`.
2. At the top of the dialog, choose `All Configurations` and `All Platforms`.
3. Navigate to `Configuration Properites > C/C++ > General`.
4. Add the Zumero include path to `Additional Include Directories`.
   See below for the location of this include path.
5. Navigate to `Configuration Properties > Linker > Input`.
6. Add `zumero_client_api.lib`, `wininet.lib`, and `zlib.lib` to
   `Additional Dependencies`.
7. Navigate to `Configuration Properties > Linker > General`.
8. Add the Zumero library path to `Additional Library Directories`.
   See below for the location of this library path.
   You may need to repeat this for individual configurations and/or platforms.
9. Click `OK`.

These paths are relative to the root of the ZSS Client SDK:

* Include Path: `include`
* Library Path: `windows/lib/PLATFORM-RUNTIME`

In the library path, `PLATFORM` is one of the following values:

* `Win32`: Use when building for the Win32 platform.
* `x64`: Use when building for the x64 platform.

and `RUNTIME` is one of the following values:

* `MD`: Use when building with the dynamic runtime (`/MD` or `/MDd` flag).
* `MT`: Use when building with the static runtime (`/MT` or `/MTd` flag).

To check which runtime you're using, look at the `Runtime Library` setting in
your project's properties under `Configuration Properties > C/C++ > Code
Generation`.  The default values are `/MD` for `Release` and `/MDd` for
`Debug`.

If your project is setup to build for multiple platforms and/or uses different
runtime settings in different configurations, then you'll need to repeat step
8 above for each configuration/platform individually, adjusting the path to
match that configuration/platform pair (as opposed to setting it once for
`All Configurations` and/or `All Platforms`).

## Calling Zumero

Once your project is setup to build with Zumero then you can just
`#include <zumero_client_api.h>` and start calling the `zumero_*` functions
declared there.  See the `sync_lib` sample in the `samples` folder for a
working project that uses the Zumero Static Library.


Zumero .NET Assembly (for Desktop)
==================================

The Zumero .NET Assembly is a thin wrapper around the Zumero Static Library
which exposes the underlying functionality as a .NET API.  It is fundamentally
two files:

1. `zumero_client_api.dll`: a native DLL containing the Zumero Static Library
   and all its dependencies (including the C/C++ runtime).
2. `Zumero.dll`: a standard .NET assembly that uses p/invoke to call functions
   in `zumero_client_api.dll`.  The source code for this wrapper assembly is
   available in the top-level `netfx` folder of the ZSS Client SDK.

The Zumero .NET Assembly has the following requirements of its caller:

1. It must target the .NET Framework 4.5.
2. It must include this assembly's runtime files (the above two DLLs) when
   deployed.

## Project Configuration

Fundamentally, you need to do two things to your project in order for it to use
the Zumero .NET Assembly:

1. Add a reference to `Zumero.dll`.
2. Configure `zumero_client_api.dll` to be deployed with the other outputs.

To add the reference, just right-click on your project's `References` node and
choose `Add Reference...`.  In the resulting dialog, click the `Browse...`
button at the bottom, and browse to the appropriate `Zumero.dll`.  See below
for the location of this file.  After you've chosen the file it will be added
to the list of available files to reference.  Make sure its box is checked and
then click OK.

To configure your project to deploy `zumero_client_api.dll`:

1. Right-click your project and choose `Add > Existing Item...`.
2. Browse to the appropriate `zumero_client_api.dll` (see below for the path).
3. Open the `Add` button's drop-down and choose `Add As Link`.
4. Right-click the new file in your project and choose `Properties`.
5. In the `Properties` window, make sure `Build Action` is set to `Content`,
   and change the `Copy to Output Directory` setting to `Copy if newer`.

The following path contains both files necessary for your project.  It is
relative to the root of the ZSS Client SDK:

    windows/netfx/PLATFORM

In the path, `PLATFORM` is one of the following values:

* `x86`: Use when building for the x86 platform.
* `x64`: Use when building for the x64 platform.

Note that you are forced to choose a platform here, and `AnyCPU` isn't an
option.  This is because `zumero_client_api.dll` is processor-specific native
code.  It's not possible for it to exist in an `AnyCPU` configuration.  There
are various ways for handling this situation, which boil down to two main
strategies:

1. Stop building your app for `AnyCPU`, and instead build it for specific
   processors.  Often you can just always build specifically for 32-bit
   processors (`x86`), and it will still run on 64-bit versions of Windows
   because 64-bit Windows can load and run 32-bit apps.  Alternatively you
   could have both 32-bit (`x86`) and 64-bit (`x64`) builds of your app.
2. Pack both/all configurations of the native DLL (`zumero_client_api.dll`)
   into an `AnyCPU` managed assembly (`Zumero.dll`) as resources, and perform
   run-time tricks in the managed assembly to unpack and load/call the correct
   native one based on which type of processor it's running on.

If your app is currently only building for `AnyCPU`, you'll have to pick one of
those two strategies and do a bit of work to implement it.

### Use Processor-Specific Builds

Option 1 is probably easier, especially if you decide to only generate 32-bit
builds.  In that case all you need to do is add the `x86` platform target to
your project and solution, and remove the `AnyCPU` platform target (or at least
stop using it, but removing it entirely may save hassle and confusion later).
These changes can be made in Visual Studio using the `Configuration Manager`
(right-click your solution and choose `Configuration Manager...`).  Once that's
done, the above instructions for referencing the Zumero DLLs are all you need;
just pick the ones in the `x86` folder, and you're done.

If you pick option 1 and want to generate a 64-bit build as well as a 32-bit
one, then you'll also need to add the `x64` platform target to your project and
solution.  Additionally, you'll need to configure your project to reference the
32-bit Zumero DLLs when building for `x86`, and the 64-bit Zumero DLLs when
building for `x64`.  Unfortunately, this configuration is not possible using
the Visual Studio UI, you have to edit the project file by hand.  We've tried
to make this easy, though: you just need to add two lines.

First, near the top of the file is a `<PropertyGroup>` tag that contains
settings such as your project's GUID, root namespace, assembly name, and so
forth.  Inside that `<PropertyGroup>` tag, add a new line:

    <ZumeroNetFxDir>SDKROOT\windows\netfx</ZumeroNetFxDir>

Replace SDKROOT with the path to the root of the ZSS Client SDK.  This could
be an absolute path, or it could be relative to the project file that you're
editing.  The point is that the value of ZumeroNetFxDir should be the path to
the `windows/netfx` folder in the ZSS Client SDK.

Second, near the bottom of the file you should find the following line:

    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

Just above that line, add this one verbatim:

    <Import Project="$(ZumeroNetFxDir)\Zumero.Windows.NetFx.props" />

This line instructs the project to import additional settings from the
referenced .props file, which is in the `windows/netfx` folder of the ZSS
Client SDK.  The settings in that .props file will configure your project to
reference the `x86` versions of the Zumero DLLs when targeting `x86`, and
reference the `x64` versions of the Zumero DLLs when targeting `x64`.

If you configure your project using this method, then you can disregard the
original instructions about configuring your project to reference the Zumero
DLLs.  The settings in the props file will do the same thing, but in a way that
supports both `x86` and `x64` builds.

Note that all of the .NET samples are configured this way, so you can reference
their project files as well as the `Configuration Manager` of the samples
solution for a working example of this setup.

### Use a "Fat" DLL

Option 2 allows you to continue to build your app for the `AnyCPU` platform,
but relies on `Zumero.dll` to be "fat", which is to say that it contains code
for both/all platforms that will be necessary, and also contains the smarts to
pick which code to use at run-time.

At this time, the ZSS Client SDK does not contain a "fat" build of
`Zumero.dll`.  However, since the source code for that DLL is included in the
SDK (in the top-level `netfx` folder), you could build one yourself if you
really wanted to.  Note that you would need to implement both parts of this
yourself:

1. Add the `zumero_client_api.dll` file from both platforms to your build of
   `Zumero.dll` as resources.
2. Add some of your own code to check which type of processor it's running on,
   then extract the matching `zumero_client_api.dll` resource and place it
   where the P/Invoke machinery will find it when needed.

## Calling Zumero

Once your project is setup to build with Zumero, you can find all of its
functionality in the `Zumero` namespace.  Generally you'll just add a
`using Zumero;` statement at the top of your code, and then start using its
types.  See the `sync_netfx` sample in the `samples` folder for a working
project that uses the Zumero .NET Assembly.
