// ------------------------------------------------------------------------------------------------
// Utils Builder
// ------------------------------------------------------------------------------------------------

YUI.add('squarespace-util', function(Y) { 


  Y.namespace("Squarespace");
  

  // ------------------------------------------------------------------------------------------------
  // Data
  // ------------------------------------------------------------------------------------------------

  Y.Data = {
  

    send: function(config, context) { // json/send receive
      
      config.context = context;

      if (!config.success) { config.failure = this._genericSuccess; }

      Y.io(config.url, {
        method: "POST",
        data: Y.JSON.stringify(config.data),
        arguments : config.arguments,
        headers: {
      		'Content-Type': 'application/json'
      	},
        on: { 
          success: Y.bind(Y.Data._connectionSuccessRouter, Y.Data, config),
          failure: Y.bind(Y.Data._connectionFailureRouter, Y.Data, config)
        }
      });

    },      
    
    sendForm: function(form, config, context) {

      config.data = form.getData();
      config.failure = { dialog: form };
      
      this.post(config, context);
      
    },


    get:  function(config, context) { this._go("GET", config, context); },
    post: function(config, context) { this._go("POST", config, context); },
      
    _go: function(method, config, context) {

      config.context = context;
    
      if (!config.success) { config.failure = this._genericSuccess; }
       
      Y.io(config.url, {
        method: method,
        arguments : config.arguments,
        data: config.data,
        on: { 
          success: Y.bind(Y.Data._connectionSuccessRouter, Y.Data, config),
          failure: Y.bind(Y.Data._connectionFailureRouter, Y.Data, config)
        }
      });

    },
  
    _genericSuccess: function(data) {
      
      console.log("Success!");
      
    },
  
    _connectionSuccessRouter: function(config, status, data, args) {

      var json;
      
      try {
        json = Y.JSON.parse(data.responseText);
      }
      catch (e) {
        this._error(config, { error: "Internal Error: Unable to parse server response from (" + config.url + ") as JSON: " + data.responseText });
        return;
      }
    
      if (json.error) {
        this._error(config, json, args);
      } else {
        config.success.apply(config.context, [ json, args ]);
      }

    },
  
    _connectionFailureRouter: function(config, status, data, args) {
    
      // normalize network errors

      this._error(config, { error: "Unable to connect to host.", network: true });
    
    },
    
    _error: function(config, json, args) {
      
      // show error using the appropriate style
      
      if (typeof(config.failure) == "function") {

        config.failure.apply(config.context, [ json, args ]);
        
      } else if (config.failure && config.failure.dialog && json.errors) {
      
        config.failure.dialog.showErrors(json.errors);

      } else {
      
        new Y.Squarespace.SystemError(json).show();

      }
      
    }

  };
  

  Y.Squarespace.SystemError = Class.create({
  
    initialize: function(data) {

      this.data = data;

    }, 
    
    show: function() {
     
      Y.one(document.body).append( 
        Y.DB.DIV({ html: this.data.error + '<br/><br/><input type="button" value="Reload Page" onclick="document.location.href = document.location.href;"/>', 
                   style: 'position: absolute; left: 15px; top: 15px; font-size: 12px; color: #fff; padding: 20px 20px 20px 80px; background: #980000 url(/universal/images-v6/error-x.png) 12px 12px no-repeat; border-radius: 5px; overflow: hidden; z-index: 10000000; width: 400px;' }) );
       
      console.log("ERROR: " + this.data.error); 

    }
    
    
  });


  // ------------------------------------------------------------------------------------------------
  // Escaping/Formatting
  // ------------------------------------------------------------------------------------------------

  Y.Squarespace.Escaping = {
    
    escapeForHtml: function(s) {

      return s.replace(/&/g,'&amp;').
               replace(/>/g,'&gt;').
               replace(/</g,'&lt;');

    },

    escapeForHtmlTag: function(s) {

      return s.replace(/&/g,'&amp;').
               replace(/>/g,'&gt;').
               replace(/</g,'&lt;').
               replace(/"/g,'&quot;');

    }

  };
  
  
  // ------------------------------------------------------------------------------------------------
  // Misc
  // ------------------------------------------------------------------------------------------------

  Y.Squarespace.Lang = {
    
    getMaxId: function(set) {
      var max = 0;
      for (i in set) { i = parseInt(i); if (i > max) { max = i; } }
      return (max);
    },

    titleToClassName: function(title) {

      title = title.toLowerCase().replace(new RegExp("[^a-zA-Z0-9 ]", "g"), "").replace(new RegExp("\\s", "g"), "-");

      if (title.length == 0) {
        return "unknown"
      } else {
        return title;
      }

    },
  
    appendCss: function(css, blockName, targetDocument) {

      if (!targetDocument) { targetDocument = document; }

      var head = targetDocument.getElementsByTagName("head")[0];

      if (blockName) {
        var existing = targetDocument.getElementById(blockName);
        if (existing) {
          head.removeChild(existing);
        }
      }

      var injectedStyle = targetDocument.createElement("style");
      injectedStyle.setAttribute("type", "text/css");
      if (blockName) { 
        injectedStyle.setAttribute("id", blockName);
      }

      if (injectedStyle.styleSheet) {
        injectedStyle.styleSheet.cssText = css;
      } else {
        injectedStyle.appendChild( targetDocument.createTextNode(css) );
      }

      head.appendChild(injectedStyle);

    }

  }
  
  
}, '1.0', { requires: ['node', 'io', 'querystring-stringify-simple'] });


// ------------------------------------------------------------------------------------------------
// DOM Builder
// ------------------------------------------------------------------------------------------------

YUI.add('squarespace-dombuilder', function(Y) { 

  
  // helper for constructing dom nodes in an ad-hoc fashion
  
  Y.DB = { 
  
    unpackData: function(n, className) {

      if (n._node) n = n._node;

      if (className) {
        while (n) { 
          if (n.data && n.className.indexOf(className) != -1) {
            return n.data;
          } 
          n = n.parentNode; 
        }  
      } else {
        while (n) { 
          if (n.data) { return n.data; }
          n = n.parentNode; 
        }  
      }

      return(null);

    },
    
    DIV: function() { return (Y.DB._gen("DIV", Array.prototype.slice.call(arguments))); }, 
    UL: function() { return (Y.DB._gen("UL", Array.prototype.slice.call(arguments))); }, 
    LI: function() { return (Y.DB._gen("LI", Array.prototype.slice.call(arguments))); }, 
    SPAN: function() { return (Y.DB._gen("SPAN", Array.prototype.slice.call(arguments))); }, 
    A: function() { return (Y.DB._gen("A", Array.prototype.slice.call(arguments))); }, 
    INPUT: function() { return (Y.DB._gen("INPUT", Array.prototype.slice.call(arguments))); }, 
    TEXTAREA: function() { return (Y.DB._gen("TEXTAREA", Array.prototype.slice.call(arguments))); },   
    SELECT: function() { return (Y.DB._gen("SELECT", Array.prototype.slice.call(arguments))); },   
    OPTION: function() { return (Y.DB._gen("OPTION", Array.prototype.slice.call(arguments))); },   
    IMG: function() { return (Y.DB._gen("IMG", Array.prototype.slice.call(arguments))); },   
  
    _gen: function(tag, args) {

      var n = document.createElement(tag);
      var examineIdx = 0;
    
      // locate classnames
    
      if (args.length > examineIdx && typeof(args[examineIdx]) == "string") {
        n.className = args[examineIdx];
        ++examineIdx;
      }
    
      // locate extended properties
      // there are more arguments, that look like objects, that are NOT arrays, that are NOT YUI.Node objects
    
      if (args.length > examineIdx && args[examineIdx] != null && typeof(args[examineIdx]) == "object" && !(args[examineIdx] instanceof Array) && (args[examineIdx].getAttribute == null) && (args[examineIdx]._node == null)) { 
    
        var props = args[examineIdx];
        ++examineIdx;
      
        // construct a deeper object
      
        for (k in props) {
          if (k == "html") {
            n.innerHTML = props[k];
          } else if (k == "data") {
            n.data = props[k];
          } else {
            n.setAttribute(k, props[k]);
          }
        }
      
        // defaults for certain objects
      
        if (tag == "A") {
          if (!props.href) { n.href = "javascript:noop();"; }
        }
      
      }
    
      // decompose an array if misused
    
      //if (args.length > examineIdx && (args[examineIdx] instanceof Array)) {
      //  args = args[examineIdx];
      //  examineIdx = 0;
      //}

      // append the rest as children
    
      n = Y.one(n);

      for (var i = examineIdx; i < args.length; ++i) {
        if (args[i] instanceof Array) {
          for (var j = 0; j < args[i].length; ++j) {
            var child = args[i][j];
            n.append(child);
          }
        } else {
          var child = args[i]
          n.append(child);
        }
      }
    
      return n;
    
    }
    
  };
  
  // YUI NODE EXTENSIONS
  
  Y.augment(Y.Node, Class.create({

    data: function(className) {

      var n = this._node;

      if (className) {
        while (n) { 
          if (n.data && n.className.indexOf(className) != -1) {
            return n.data;
          } 
          n = n.parentNode; 
        }  
      } else {
        while (n) { 
          if (n.data) { return n.data; }
          n = n.parentNode; 
        }  
      }

      return (null);

    },

    model: function(className) {

      var n = this._node;

      while (n) { 
        if (n.data && n.data.model) { return n.data.model; }
        n = n.parentNode; 
      }  

      return (null);

    },

    part: function(name) { 

      var els = this._node.getElementsByClassName(name);
      return (els && els.length ? Y.one(els[0]) : null);

    },
    
    ancestorWithClass: function(classes) {
      
      if (typeof(classes) == "string") {
        classes = [classes];
      }

      var test = function(n) {

        for (var i = 0; i < classes.length; ++i) {
          if (n.hasClass(classes[i])) { return n; }
        }

        return false;

      };

      return (test(this) || this.ancestor(test));

    }

  }));
  

}, '1.0', { requires: ['node'] });



/* BUILDER TEST!

console.log( 

  DB.DIV("grid-container-controls", 
    DB.DIV("ok",
      DB.SPAN("hmm", { html: "LABEL!"}),
      DB.SPAN("hmm", { html: "LABEL!"})
      ),
    DB.DIV("control-block", { html: "test" }),
    DB.DIV("control-block", { html: "test" })
  ).innerHTML

  );*/

  

