Initial commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0a5844d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.DS*
+.waf*
+build
+.lock-*
+osx/Frameworks/Sparkle*
+waf-tools/*.pyc
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c0cd90e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2013, Regents of the University of California
+All rights reserved.
+
+Authors of individual source files and components are listed in the
+respective files.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Regents of the University of California nor
+      the names of its contributors may be used to endorse or promote
+      products derived from this software without specific prior written
+      permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL REGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/osx/Info.plist b/osx/Info.plist
new file mode 100644
index 0000000..24e72d7
--- /dev/null
+++ b/osx/Info.plist
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+    <key>CFBundleExecutable</key>
+    <string>NDNx Control Center</string>
+    <key>CFBundleGetInfoString</key>
+    <string>Created by Waf</string>
+    <key>CFBundleIconFile</key>
+    <string>ndnx-main.icns</string>
+    <key>CFBundleIdentifier</key>
+    <string>net.named-data.control-center</string>
+    <key>CFBundlePackageType</key>
+    <string>APPL</string>
+    <key>CFBundleSignature</key>
+    <string>????</string>
+    <key>NOTE</key>
+    <string>THIS IS A GENERATED FILE, DO NOT MODIFY</string>
+    <key>NSPrincipalClass</key>
+    <string>NSApplication</string>
+    <!-- <key>LSUIElement</key> -->
+    <!-- <string>1</string> -->
+</dict>
+</plist>
diff --git a/osx/main.mm b/osx/main.mm
new file mode 100644
index 0000000..edc5186
--- /dev/null
+++ b/osx/main.mm
@@ -0,0 +1,13 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * @copyright See LICENCE for copyright and license information.
+ *
+ * @author Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, char *argv[])
+{
+    return NSApplicationMain(argc, (const char **)argv);
+}
diff --git a/osx/ndnx-main.icns b/osx/ndnx-main.icns
new file mode 100644
index 0000000..ececc16
--- /dev/null
+++ b/osx/ndnx-main.icns
Binary files differ
diff --git a/osx/ndnx-tray.icns b/osx/ndnx-tray.icns
new file mode 100644
index 0000000..f347dd7
--- /dev/null
+++ b/osx/ndnx-tray.icns
Binary files differ
diff --git a/osx/sparkle-auto-update.h b/osx/sparkle-auto-update.h
new file mode 100644
index 0000000..88f8c66
--- /dev/null
+++ b/osx/sparkle-auto-update.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * @copyright See LICENCE for copyright and license information.
+ *
+ * @author Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * @author Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef SPARKLE_AUTO_UPDATE_H
+#define SPARKLE_AUTO_UPDATE_H
+
+/**
+ * @brief Class implementing interface for automatic updates for OSX using Sparkle framework
+ */
+class SparkleAutoUpdate
+{
+public:
+  /**
+   * @brief Constructor
+   * @param updateUrl URL to Sparkle update definition file
+   */
+  SparkleAutoUpdate (const char *updateUrl);
+  ~SparkleAutoUpdate ();
+
+  /**
+   * @brief Check for updates once
+   */
+  void
+  checkForUpdates ();
+
+private:
+  class Private;
+  Private *d;
+};
+
+#endif // SPARKLE_AUTO_UPDATE_H
diff --git a/osx/sparkle-auto-update.mm b/osx/sparkle-auto-update.mm
new file mode 100644
index 0000000..a1dc5c0
--- /dev/null
+++ b/osx/sparkle-auto-update.mm
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * @copyright See LICENCE for copyright and license information.
+ *
+ * @author Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * @author Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "sparkle-auto-update.h"
+
+#import <Foundation/Foundation.h>
+#import <AppKit/AppKit.h>
+#import <Sparkle/Sparkle.h>
+
+class SparkleAutoUpdate::Private
+{
+public:
+  SUUpdater *updater;
+};
+
+SparkleAutoUpdate::SparkleAutoUpdate(const char *updateUrl)
+{
+  d = new Private;
+  d->updater = [[SUUpdater sharedUpdater] retain];
+  NSURL *url = [NSURL URLWithString: [NSString stringWithCString:updateUrl encoding:NSASCIIStringEncoding]];
+  [d->updater setFeedURL: url];
+  [d->updater setAutomaticallyChecksForUpdates: YES];
+  [d->updater setUpdateCheckInterval: 86400];
+}
+
+SparkleAutoUpdate::~SparkleAutoUpdate()
+{
+  [d->updater release];
+  delete d;
+  // presummably SUUpdater handles garbage collection
+}
+
+void SparkleAutoUpdate::checkForUpdates()
+{
+  //[d->updater checkForUpdatesInBackground];
+  [d->updater checkForUpdates : nil];
+}
diff --git a/waf b/waf
new file mode 100755
index 0000000..cacc63a
--- /dev/null
+++ b/waf
Binary files differ
diff --git a/waf-tools/sparkle.py b/waf-tools/sparkle.py
new file mode 100644
index 0000000..67cf6d9
--- /dev/null
+++ b/waf-tools/sparkle.py
@@ -0,0 +1,49 @@
+#! /usr/bin/env python
+# encoding: utf-8
+
+from waflib import Logs
+from waflib.Configure import conf
+
+@conf
+def check_sparkle_base (self, *k, **kw):
+  self.check_cxx (framework_name="Sparkle", header_name=["Foundation/Foundation.h", "AppKit/AppKit.h"],
+                  uselib_store='OSX_SPARKLE', define_name='HAVE_SPARKLE',
+                  compile_filename='test.mm', use="OSX_FOUNDATION OSX_APPKIT",
+                  *k,
+                  **kw
+                  )
+
+@conf
+def check_sparkle (self, *k, **kw):
+    try:
+        self.check_sparkle_base (*k, **kw)
+    except:
+        try:
+            # Try local path
+            # Logs.info ("Check local version of Sparkle framework")
+            self.check_sparkle_base (cxxflags="-F%s/osx/Frameworks/" % self.path.abspath(),
+                                     linkflags="-F%s/osx/Frameworks/" % self.path.abspath())
+        except:
+            import urllib, subprocess, os, shutil
+            if not os.path.exists('osx/Frameworks/Sparkle.framework'):
+                # Download to local path and retry
+                Logs.info ("Sparkle framework not found, trying to download it to 'build/'")
+
+                urllib.urlretrieve ("http://sparkle.andymatuschak.org/files/Sparkle%201.5b6.zip", "build/Sparkle.zip")
+                if os.path.exists('build/Sparkle.zip'):
+                    try:
+                        subprocess.check_call (['unzip', '-qq', 'build/Sparkle.zip', '-d', 'build/Sparkle'])
+                        os.remove ("build/Sparkle.zip")
+                        if not os.path.exists("osx/Frameworks"):
+                            os.mkdir ("osx/Frameworks")
+                        os.rename ("build/Sparkle/Sparkle.framework", "osx/Frameworks/Sparkle.framework")
+                        shutil.rmtree("build/Sparkle", ignore_errors=True)
+
+                        self.check_sparkle_base (cxxflags="-F%s/osx/Frameworks/" % self.path.abspath(),
+                                                 linkflags="-F%s/osx/Frameworks/" % self.path.abspath())
+                    except subprocess.CalledProcessError as e:
+                        self.fatal("Cannot find Sparkle framework. Auto download failed: '%s' returned %s" % (' '.join(e.cmd), e.returncode))
+                    except:
+                        self.fatal("Unknown Error happened when auto downloading Sparkle framework")
+def configure(conf):
+    conf.check_sparkle ()
diff --git a/wscript b/wscript
new file mode 100644
index 0000000..6f0c6b9
--- /dev/null
+++ b/wscript
@@ -0,0 +1,48 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+VERSION='1.0'
+APPNAME='ndnx-control-center'
+
+from waflib import Logs, Utils, Task, TaskGen
+
+def options(opt):
+    opt.load('compiler_c compiler_cxx')
+    opt.load('sparkle', tooldir='waf-tools')
+
+def configure(conf):
+    conf.load('compiler_c compiler_cxx')
+
+    if Utils.unversioned_sys_platform () != "darwin":
+        Logs.error ("Only OSX is supported so far")
+        return -1
+
+    if Utils.unversioned_sys_platform () == "darwin":
+        conf.check_cxx(framework_name='Foundation', uselib_store='OSX_FOUNDATION', compile_filename='test.mm')
+        conf.check_cxx(framework_name='AppKit',     uselib_store='OSX_APPKIT',     compile_filename='test.mm')
+        conf.check_cxx(framework_name='Cocoa',      uselib_store='OSX_COCOA',     compile_filename='test.mm')
+
+        conf.load('sparkle')
+
+def build (bld):
+    if Utils.unversioned_sys_platform () != "darwin":
+        Logs.error ("Only OSX is supported so far")
+        return -1
+
+    if Utils.unversioned_sys_platform () == "darwin":
+        bld (
+            target = "NDNx Control Center",
+            features=['cxxprogram', 'cxx'],
+            includes = "osx",
+            mac_app = "NDNx Control Center.app",
+            source = bld.path.ant_glob ('osx/**/*.mm'),
+            use = "OSX_FOUNDATION OSX_APPKIT OSX_COCOA OSX_SPARKLE",
+
+            mac_plist = bld.path.find_resource('osx/Info.plist').read (),
+            mac_resources = 'osx/ndnx-main.icns osx/ndnx-tray.icns',
+            mac_frameworks = "osx/Frameworks/Sparkle.framework",
+            )
+
+from waflib import TaskGen
+@TaskGen.extension('.mm')
+def m_hook(self, node):
+    """Alias .mm files to be compiled the same as .cc files, gcc/clang will do the right thing."""
+    return self.create_compiled_task('cxx', node)