// Copyright (c) 2009 Alexander Fritze
// For license details please contact <alex@croczilla.com>
// -------------------------------------------------------------------
//
// oni-ajax v0.3
//
// Oni library for ajax programming
// See http://www.croczilla.com/oni for details
//
// Generated from oni-ajax.js.in
//


(function () {


//----------------------------------------------------------------------
// helpers

// create an array from a function's arguments object, starting at the
// i's parameter
function slice_args(a, /*[opt]*/ i) {
  return Array.prototype.slice.call(a, i);
}

// call 'fct' asynchronously
function callAsync(fct) {
  window.setTimeout(fct, 0);
}

//----------------------------------------------------------------------
// DOM-related functions

var DOM = {};
this["DOM"] = DOM;

DOM.WaitForEvent = ALift(
  function(cont, event, element) {
    function listener(e) {
      cancel();
      cont([true, e]);
    }

    function cancel() {
      if (element.removeEventListener)
        element.removeEventListener(event, listener, true);
      else
        element.detachEvent("on"+event, listener);
    }

    if (element.addEventListener)
      element.addEventListener(event, listener, true);
    else
      element.attachEvent("on"+event, listener);

    return cancel;
  });

DOM.ElementById = SLift(function(id) { return document.getElementById(id); });

DOM.Alert = SLift(function(mes) { window.alert(mes); });

//----------------------------------------------------------------------
// DOM.LoadScript(url)

var loaded_scripts = {};
var pending_scripts = {};
DOM.LoadScript = ALift(
  function(cont, url) {
    if (loaded_scripts[url]) {
      // already loaded
      callAsync(function() { cont([true, true]); });
      return;
    }
    
    var continuations = pending_scripts[url];
    if (!continuations) {
      pending_scripts[url] = continuations = [];
      var elem = document.createElement("script");

      function done() {
        delete pending_scripts[url];
        loaded_scripts[url] = true;
        document.getElementsByTagName("head")[0].removeChild(elem);
        for (var i=0;i<continuations.length;++i)
          continuations[i]([true, true]);
        delete continuations;
      }

      function listener(e) {
        elem.removeEventListener("load", listener, false);
        done();
      }
      
      function listenerIE(e) {
        if (e.srcElement.readyState == "loaded" ||
            e.srcElement.readyState == "complete") {
          elem.detachEvent("onreadystatechange", listenerIE);
          done();
        }
      }

      if (elem.addEventListener)
        elem.addEventListener("load", listener, false);
      else // IE
        elem.attachEvent("onreadystatechange", listenerIE);

      // kick off the load:
      elem.src = url;
      document.getElementsByTagName("head")[0].appendChild(elem);
    }

    continuations.push(cont);
    
    return null; 
  });

//----------------------------------------------------------------------
// Google API

var Google = {};
this["Google"] = Google;

Google.EnsureAPI = Defun([],
                         If(SLift(function() {
                             return !window.google || !window.google.load; })(),
                            DOM.LoadScript("http://www.google.com/jsapi")));

Google.Load = Defun(["moduleName", "moduleVersion"],
                    Google.EnsureAPI(),
                    ALift(function(cont, moduleName, moduleVersion) {
                      google.load(moduleName, moduleVersion,
                                  {"callback":function() { cont([true, true]); }});
                      return null;
                    })(Get("moduleName"), Get("moduleVersion")));

//----------------------------------------------------------------------
// Google Feeds API

Google.Feeds = {};

Google.Feeds.Load = Defun(["url", "numEntries"],
                          Google.Load("feeds", "1"),
                          ALift(function(cont, url, numEntries) {
                            var feed = new google.feeds.Feed(url);
                            if (!numEntries) numEntries = 20;
                            feed.setNumEntries(numEntries);
                            feed.load(function(result) {
                              if (result.error)
                                cont([false, result.error])
                              else
                                cont([true, result.feed]);
                            });
                          })(Get("url"), Get("numEntries")));

//----------------------------------------------------------------------
// Google Language API

Google.Language = {};

// helpers for Google.Language.Translate:
var TranslateInner = ALift(
  function(cont, text, srcLang, destLang, type) {
    if(!text || !text.length) {
      callAsync(function() { cont([true, {translation:""}]); });
      return;
    }

    if (!type) type = 'html';
    google.language.translate({text:text, type:type}, srcLang, destLang,
                              function(result) {
                                if (result.error)
                                  cont([false, result.error])
                                else
                                  cont([true, result]);
                              });
  });

var StrSplit = SLift(
  function(str) {
    var arr = [];
    var length = str.length;
    var start = 0;
    while (length - start > 1100) {
      var split = start + 1100;
      // search for a '>' or space within 1000 - 1100 characters:
      for (var i = start + 1100; i > start + 1000; --i) {
        if (str[i] == ' ') {
          // if we find nothing better, we'll split the text here
          // (we don't break yet, because we might be inside a tag here)
          split = i;
        } else if (str[i] == '>') {
          // we'll assume that this is a closing tag; a good place to split the text
          split = i+1;
          break;
        } else if (str[i] == '<') {
          // we'll assume that this is an opening tag
          split = i;
          break;
        }
      }
      arr.push(str.slice(start, split));
      start = split;
    }
    if (length - start) {
      arr.push(str.slice(start));
    }
    return arr;
  });

var StrJoin = SLift(
  function(a,b) {
    return a+" "+b;
  });

// default type: 'html'
Google.Language.Translate =
  Defun(["text", "srcLang", "destLang", "type"],
        Google.Load("language", "1"),
        Let({ TranslateList : Lambda(["lst"],
                                     If(IsNull(Get("lst")),
                                        {translation:""},
                                        Let({ trans: TranslateInner(Car(Get("lst")),
                                                                    Get("srcLang"),
                                                                    Get("destLang"),
                                                                    Get("type"))
                                            },
                                            Obj("translation",
                                                StrJoin(ObjMem(Get("trans"), "translation"),
                                                        ObjMem(Get("TranslateList")(GetCdr("lst")),
                                                               "translation")),
                                                "detectedSourceLanguage",
                                                ObjMem(Get("trans"), "detectedSourceLanguage")))))
            },
            Get("TranslateList")(StrSplit(Get("text")))));

Google.Language.Detect =
  Defun(["text"],
        Google.Load("language", "1"),
        ALift(function(cont, text) {
          google.language.detect(text,
                                 function(result) {
                                   if (result.error)
                                     cont([false, result.error])
                                   else
                                     cont([true, result]);
                                 });
        })(Get("text")));

Google.Language.GetBranding = Defun(["elem", "options"],
                                    Google.Load("language", "1"),
                                    SLift(function(e, o) {
                                      return google.language.getBranding(e, o);
                                    })(Get("elem"), Get("options")));

//----------------------------------------------------------------------
//

})()
