/**
 * The Hackademix Framework
 * Copyright 2007-... Giorgio Maone
 *
*/

var HX = {}

HX.SQL = function(dbtype) {
  this.dbtype = dbtype || "MS_SQL_Server";
  this.encoder = HX.SQL.Encoders[this.dbtype];
}

HX.SQL.prototype = {
  prepareStatement: function(s, parms) {
    if(!typeof(parms) == "object") return s;
     var encode = this.encoder;
     function handleEqualsNull(s) {
       s = encode(s);
       return s ? "= " + s : "IS NULL";
     }
    return (parms instanceof Array) 
      ? s.replace(/(?:=\s*)?\?/g, function($0) { 
        return HX.SQL.replace($0, encode(parms.shift()));
      }) 
      : s.replace(/(?:=\s*)?@(\w+)/g, function($0, $1) {
        return HX.SQL.replace($0, encode(parms[$1]));
      });
  }
};
HX.SQL.replace = function(subj, repl) { 
  return (subj.charAt(0) == "=")
    ? (repl ? "= " + repl : "IS NULL") 
    : repl || "NULL";
};
HX.SQL.encode = function(s, concatenator, charFnName) {
  if(!(s || typeof(s) == "number")) return s;
  var cc = [];
  for(var j = 0; j < s.length; j++) {
    cc.push(charFnName.concat("(" + s.charCodeAt(j) + ")"));
  }
  return cc.join(concatenator);
};

HX.SQL.Encoders = {
  MS_SQL_Server: function(s) {
    return HX.SQL.encode(s, " + ", "char"); 
  },
  MS_Access: function(s) {
    return HX.SQL.encode(s, " & ", "chr"); 
  },
  Oracle: function(s) {
    return HX.SQL.encode(s, " || ", "chr"); 
  },
  MySQL: function(s) {
    return (s = HX.SQL.encode(s, ", ", "char")) ? "concat(" + s + ")" : s; 
  }
};

HX.URL = {
  encode: function(s) {
    return s.replace(/./g, function(c) {
      var n = c.charCodeAt(0).toString(16);
      if(n.length == 1) n = "0".concat(n);
      return "%" + n;
    });
  },
  
  safeDecode: function(s) {
    try {
      return decodeURIComponent(s);
    } catch(e) {
      return unescape(e);
    }
  },
  
  hashPersist: function(f) {
    var all = HX.Form.getFields(f);
    var params = [], el, value, k;
    for(var j = 0, len = all.length; j < len; j++) {
      value = HX.Form.getValue(el = all[j]);
      
      if(value === null) continue;
      if(!(value instanceof Array)) {
        value = [value];
      }
      for(k = 0; k < value.length; k++) {
        params.push(encodeURIComponent(el.name) + "=" + encodeURIComponent(value[k]));
      }
    }
    location.hash = "#" + encodeURI(params.join(";"));
  },
  
  hashLoad: function(f) {
    var s = location.hash.replace(/^#/, '');
    if(!s) return;
    
    f.reset();
   
    var parms = decodeURI(s).split(";");

    var parts, name, value, el, k;
    var all = HX.Form.getFields(f);
    
    for(var j = 0; j < parms.length; j++) {
      parts = parms[j].split("=");
      name = this.safeDecode(parts[0]);
      value = this.safeDecode(parts[1]);
      el = null;
      for(k = 0; k < all.length; k++) {
        if(all[k].name == name) {
          el = all.splice(k, 1)[0];
          break;
        }
      }
      if(el) {
        HX.Form.setValue(el, value);
      }
    }
  }
};

HX.Form = {
  getFields: function(f) {
    var all = [];
    all.enlist = function(els) {
      for(var j = 0; j < els.length; j++) {
        this.push(els[j]);
      }
      return this;
    };
    all.enlist(f.getElementsByTagName("input"))
      .enlist(f.getElementsByTagName("textarea"))
      .enlist(f.getElementsByTagName("select"));
    return all;
  },
  getValue: function(el) {
    switch(el.type) {
      case "select-one":
        return el.selectedIndex > -1 ? el.options[el.selectedIndex].value : null;
      
      case "select-multi":
        var values = [];
        for(k = el.options.length; k-- > 0;) {
          if(el.options[k].selected) values.push(el.options[k].value);
        }
        return values;
      case "checkbox":
      case "radio":
        return el.checked ? el.value : null;

      case "text":
       case "textarea":
        return el.value;
        
      case "submit":
      case "button":
      break;
      default:
        return null;
    }
  },
  setValue: function(el, value) {
    switch(el.type) {
      case "select-one":
      case "select-multi":
 
        for(var j = el.options.length; j-- > 0;) {
          if(el.options[j].value == value) { 
            el.options[j].selected = "selected";
            el.selectedIndex = j;
          }
        }
      break;
      case "text":
      case "textarea":
      case "password":
      case "hidden":
        el.value = value;
      break;
      case "radio":
      case "checkbox":
        if(el.value == value) el.checked = true;
      break;
    }
  }
}

HX.DOM = {
  setText: function(node, s) {
    node.innerHTML = "";
    node.appendChild(document.createTextNode(s));
    return node;
  },
  xmlEntities: {
    '"': "&quot;",
    '&': "&amp;",
    '<': "&lt;",
    '>': "&gt;"
  },
  escapeXML: function(s) {
    return s.replace(/<>&"/g, function(ent) {
      return this.xmlEntities[ent];
    });
  },
  createNamed: function(tag, name) {
    var node;
    try {
      node = document.createElement('<' + tag + ' name="' + this.escapeXML(name) + '">');
    } catch(e) {
      node = document.createElement(tag);
    }
    node.name = name;
    return node;
  }
};

HX.Nav = {
  buildMetaRefresh: function(url) {
    var meta = document.createElement("meta");
    meta.setAttribute("http-equiv", "Refresh");
    meta.setAttribute("content", "0;URL=" + url);
    return meta;
  },
  
  pageURL: function(content) {
    if(content && typeof(content) == "object") { 
      var container = document.createElement("div");
      container.appendChild(content);
      content = container.innerHTML;
    }
    // alert(content);
    return /\bKHTML\b/i.test(navigator.userAgent)
      ? "data:text/html," + content
      : encodeURI('javascript:decodeURIComponent("' + encodeURIComponent(content) + '");');
  },
  
  buildRefreshURL: function(url, post) {
    url = url.replace(/[^%]/g, encodeURI);
    if(post) return this.pageURL(this.buildPost(url, true));
    return this.pageURL(/*
      /MSIE/.test(navigator.userAgent)
        ? this.buildFormRefresh(url)
        : */ this.buildMetaRefresh(url)
    );
  },
  
  buildFormRefresh: function(url) {
    var f = document.createElement("form");
    f.method = "get";
    f.action = url;
    return this.makeAutoSubmit(f);
  },
  
  buildPost: function(url, autoSubmit) {
    var parts = url.split("?");
    
    // take last slice, so you can use two "?..." blocks to have different GET and POST parameters
    var parms = parts.pop().split("&"); 
    url = parts.join("?");
    var form = document.createElement("form");
    form.method = "post";
    form.action = url;
    var input;
    for(var j = 0, len = parms.length; j < len; j++) {
      parts = parms[j].split("=");
      input = HX.DOM.createNamed("textarea", HX.URL.safeDecode(parts[0]));
      HX.DOM.setText(input, HX.URL.safeDecode(parts[1]));
      form.appendChild(input);
    }
    if(autoSubmit) {
      this.makeAutoSubmit(form);
    }
    return form;
  },
  
  makeAutoSubmit: function(form) {
     form.innerHTML += 
        '<scr' + 'ipt type="text/javascript">window.onload = function() { document.forms[0].submit(); };</scr' + 'ipt>'; 
     return form;
  },
  
  anonOpen: function(url, target, post) {
    var jsURL = this.buildRefreshURL(url, post);
    
    if(target) {
      if(typeof(target) == "object" && target.contentDocument || target.contentWindow) {
        // iframe?
        //target.src = jsURL;
        //return;
        window.setTimeout(function() {
          (target.contentDocument || target.contentWindow).location.href = jsURL;
        }, 50);
      } else {
        // new window
        var features = null;
        if(target.indexOf("&") > 0) {
          features = target.split("&");
          target = features[0];
          features = features[1];
          window.open(jsURL, target, features);
        } else {
          window.open(jsURL, target);
        }
      }
    } else {
      // self
      location.href = jsURL;
    }
  }
}



var $ = $ || function(id) { return document.getElementById(id); };
