Back to docs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

// This is from the reference we set to AlchemiumInterfaces.dll 
// The AlchemiumInterfaces.dll assembly is located in the SDK_ROOT\ext directory
// With each new application you build it will live in the ./app/ext directory, 
// which also where you put any extensions you want the application to use.
using AlchemiumInterfaces;

namespace SampleExtension
{
    public class Class1 : AlchemiumInterfaces.IAlchemiumExt
    {

        private IAlchemiumAPI _api;
        
        // This is the first call Alchemium will make after instantiating our
        // extension.  We will hold on the the _api reference passed to 
        // us for future use in communicating with the host.
        
        void IAlchemiumExt.init(IAlchemiumAPI api)
        {
            // Stash the reference to the host API
            _api = api;
        }

		void IAlchemiumExt.closeDown()
        {

            // Called by the ALchemium runtime when the host application is closing
            // Do any required recource cleanup here
        }

        // This is the fully qualified object name.  Note, the reverse domain 
        // naming scheme is required to avoid collisions

        string IAlchemiumExt.objectName
        {
            // This will be the object prefix to our extension in JavaScript
            get { return "com.electricplum.myExt"; }
        }

        // Return the list of function names you are going to present to 
        // JavaScript via your object.  when JS calls one of these functions, 
        // The IAlchemiumExt.invoke implementation will be called in this extension
        
        List<string> IAlchemiumExt.getFunctionNames()
        {
            var funcs = new List<string>();
            funcs.Add("func1");
            funcs.Add("func2");

            // ... etc ...
            // These will all ultimately be hanging off your object name 
            // for example com.electricplum.myExt.func1();

            return funcs;

        }

        // Each time JavaScript on the page makes a call to one of our registered 
        // functions, IAlchemiumExt.invoke() will be called.  Here we handle 
        // the call and return a response
        
        Dictionary<string, object> IAlchemiumExt.invoke(string methodName, Dictionary<string, object> argsIn)
        {
            // In JavaScript you call these functions using the prefix returned by 
            // our implementation of IAlchemiumExt.objectName
            // So in this example we would use this JS code:
            //
            //  var ret = com.electricplum.myExt.func1({someParam: 'passing this to .net'});
            //  var ret = com.electricplum.myExt.func2();
            //

            // We will populate this dictionary with our return values
            var ret = new Dictionary<string, object>();

            switch (methodName)
            {
             
                case "func1":
                    
                    // This function returns an object with 2 properties "prop1" and "prop2"
                    ret.Add("prop1", 42);

                    // If the JS caller passed in a param named "someParam" echo it in the "prop2" 
                    // property of the object we return
                    if (argsIn.ContainsKey("someParam"))
                    {
                        ret.Add("prop2", "Hello, you passed in " + argsIn["someParam"]);
                    }
                    else
                    {
                        ret.Add("prop2", "Hello, you didn't pass a value for someParam");
                    }
                    return ret;

                case "func2":

                    // Example of using the Alchemium API's stringify method to pass 
                    // back a native c# object in JSON format.  We can use JSON.parse() in 
                    // JavaScript to deserialize it to a JS object
                    var o = new SerializeTest();
                    o.propertyOne = "I am property one";
                    o.propertyTwo = 3.14;
                    ret.Add("obj", _api.stringify(o));
                    return ret;

                default:
                    return null;
            }
            
        }
        
        // Register for custom schemes we'll listen for any requests (href, AJAX etc) to these uri schemes
        // will be routed to our implementation of IAlchemiumExt.processCustomSchemeRequest
        
        List<AlchemiumScheme> IAlchemiumExt.getCustomSchemes()
        {
            var schemeList = new List<AlchemiumScheme>();
            var myScheme = new AlchemiumScheme();

            // http is the preferred prefix to avoid having to deal with the host Alchemium browser 
            // imposing security restrictions on things like post data to non standard URI schemes
            myScheme.uriPrefix = "http";
            myScheme.domain = "myextension.com";
            myScheme.mimeType = "text/html";

            schemeList.Add(myScheme);
            // At this point, any request to "http://myExtension.com/*" (AJAX, href etc.) will 
            // be routed to our implementation of IAlchemiumExt.processCustomSchemeRequest()
            return schemeList;
        }


        // A request for a resource was made (either from the HTML content or AJAX) 
        // to a scheme that matches one that we are listening for
        // We show both variants here.  First we handle an AJAX request/response, and 
        // next we see how we could silmply return content as if it were generated 
        // server-side.
        
        void IAlchemiumExt.processCustomSchemeRequest(string uri, 
                                                      Dictionary<string, object> postData, 
                                                      ref string responseMimeType, 
                                                      ref string response)
        {
            // If we get a request for http://myExtension.com/ajax treat this as an an AJAX call
            if (uri.ToLower().EndsWith("ajax"))
            {
                // postData is passed in populated with the POST variables if the client did a AJAX POST
                // We could access those here if we wanted.  It will be null if there were no POST variables 
                if (postData != null)
                {
                    foreach (var item in postData)
                    {
                        Debug.WriteLine("Passed in variable named: " + item.Key);
                    }
                
                }
                responseMimeType = "application/json";
                var responseObj = new SerializeTest();
                responseObj.propertyOne = "Hello from c#!";
                responseObj.propertyTwo = 42;

                // Need to respond with JSON so use the Alchemium API helper stringify()
                response = (string)_api.stringify(responseObj);

            }
            else
            {   
                // For all other requests to our URI just return some HTML.  
                // Alchemium does not require well formed HTML, so for this example we'll be lazy and just 
                // spit a <div> and show an alert.  Note how we are also referencing an 
                // <a:include> tag.  Alchemium will automatically inject the include's contents into 
                // the reponse stream on our behalf.  The only requirement is that the data-file referenced in the 
                // include is in the [Path to Your app]\app\includes\*.* folder.
                
                response = "<a:include data-file='deps.html' /><div class='well'>" + 
                           "I will be rendered in the Alchemium browser in a twitter Bootstrap " + 
                           "well</div><script>alert('Back from c#!');</script>";
            }
        }
        
        // Called whenever an element is clicked in the DOM
        // You recive the url of the active page, and target element id, name and html
        
        void IAlchemiumExt.DOMClick(string url, string id, string name, string elementHTML)
        {
           // Do something based on what the user clicked in the DOM
        }
        
        
        // Not used yet.  For future use in Gallery/App store type scenarios.
        string IAlchemiumExt.description
        {
            get { return "My Extension"; }
        }
    
        // Not used yet.  For future use in Gallery/App store type scenarios.
        string IAlchemiumExt.helpHTML
        {
            get
            {
                return "Help text here";
            }
        }
        
        // Not used yet.  For future use in Gallery/App store type scenarios.
        string IAlchemiumExt.name
        {
            get { return "My Extension"; }
        }
        
    }

    
    // Just a test object for serialization example
    public class SerializeTest
    {
        private string _propertyOne = "";
        private double _propertyTwo = 0;

        public string propertyOne
        {

            get
            {
                return _propertyOne;
            }

            set
            {
                _propertyOne = value;
            }
        }

        public double propertyTwo
        {

            get
            {
                return _propertyTwo;
            }

            set
            {

                _propertyTwo = value;
            }
        }
    }
   
}