﻿
var cUID = 0;
UID = function() {
    var res = 'obj' + cUID;
    cUID++;
    return res;
}

nE = function(tagName) {
    var r = cE(tagName);
    return r;
}

nD = function(innerHTML, className) {
    var r = nE('div');
    if (innerHTML) r.innerHTML = innerHTML;
    if (className) setClass(r, className);
    return r;
}
nS = function(innerHTML) {
    var r = nE('span');
    if (innerHTML) r.innerHTML = innerHTML;
    return r;
}

nDClearAll = function() {
    var r = nD();
    setClass(r, 'clearall');
    return r;
}

nLbl = function(id, text) {
    var nl = nE('label');
    nl.innerHTML = text;
    nl['for'] = id;
    //nl.control = this;
    //nl.onclick = this.sLbl_click;
    return nl;
}

nTxt = function(id) {
    res = nE('input');
    res.id = id;
    res.type = 'text';
    return res;
}

nBtn = function(text) {
    res = nE('button');
    res.innerHTML = text;
    return res;
}

cE = function(t) {
    return document.createElement(t);
}
Sample = new Object();
Sample.div = nD();

// choose horizontal / vertical alignment.
// for the moment, just horizontal.
RadioGroup = function(container, name) {
    this.container = container;
    this.name = name;
    this.init(0);
}
var p = RadioGroup.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    this.superInit(depth);
    this.controls = new Array();
    //var d = this.createMyDiv();
    
    this.addMyDiv();
}
p.validateItemSelected = function() {
    // radioGroup should hold a reference to each radio button it contains.
    //  perhaps using a DIV would be best for this.
    var res = false;
    for(var c = 0; c < this.controls.length; c++) {
        if (this.controls[c].iRb.checked) res = true;
    }
    return res;
}

EventArgument = function(name, value) {
    this.name = name;
    this.value = value;
}

RaiseEvent = function(sender, name, arg1) {
    var controlUid = idxElementsControls[sender.id];
    var control = idxControls[controlUid];
    
    // then alert the control that this event has occurred with this element.
    if (control.notify) control.notify(sender, name, arg1);
    
}

DataCell = function(container, columnName, innerHTML) {
    this.container = container;
    this.columnName = columnName;
    this.innerHTML = innerHTML;
    this.init();
}
var p = DataCell.prototype;
p.inheritFrom(Control);
p.init = function(depth) {
    this.superInit(depth);
    // may need to look somewhere to get the styling.
    if (this.columnName) this.setClass('dataCell' + this.columnName); else this.setClass('dataCell');
    if (this.innerHTML) this.div.innerHTML = this.innerHTML;
    
}

//COption = function(container, name) {
//    this.container = container;
//    this.name = name;
//    this.init(0);
//}
//var p = COption.prototype;
//p.inheritFrom(Control);
//p.init = function(depth) {
//    this.superInit(depth);
//    this.el = nE('option');
//    this.el.name = this.name;
//    this.addMyEl();
//}

// could set its inner html according to its items.

//ListBox = function(container) {
//    this.container = container;
//    this.init(0);
//}
//var p = ListBox.prototype;
//p.inheritFrom(Control);
//p.init = function(depth) {
//    this.superInit(depth);
//    this.el = nE('
//    this.addMyEl();
//}

ProgressIndicator = function(container, aStages) {
    this.container = container;
    this.aStages = aStages;
    this.init(0);
}
var p = ProgressIndicator.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    this.superInit(depth);
    this.setClass('ProgressIndicator');
    this.render();
    this.addMyEl();
}
p.render = function() {
    // this creates Divs inside based on the stages it has
    // make it show the 'on' colour for all previous stages as well as the current one.
    
    var sb = new StringBuilder();
    sb.append('<div>');
    for (var c = 0; c < this.aStages.length; c++) {
        sb.append(this.aStages[c].toHTML(c <= this.stageNumber - 1));
    }
    sb.append('<div class="clearall" /></div>');
    //this.el.innerHTML = sb.toString();
    
    this.setInnerHTML(sb.toString());
}
p.selectStage = function(stageNumber) {
    //alert('selectStage ' + id);
    //alert('this.selectedStageId ' + this.selectedStageId);
    var tsn = stageNumber;
    stageNumber = Math.floor(stageNumber);
    
    if (this.stageNumber) {
        //var oldID = this.selectedStageId;
        //this.stages[this.selectedStageId].selected = false;
        var idx = this.getStageIndexById(Math.floor(this.stageNumber));
        this.aStages[idx].setSelected(false, this);
        
    }
    var idx = this.getStageIndexById(stageNumber)
    this.aStages[idx].setSelected(true, this);
    //this.selectedStageId = stageNumber;
    // need to update the appearance of the control.
    this.stageNumber = tsn;
}
p.getStageIndexById = function(id) {
    // stages are held in an array.
//    for (var c = 0; c < this.aStages.length; c++) {
//        if (this.aStages[c].
//    }
    //alert ('id ' + id);
    return id - 1;
}

DropDownListWithMore = function(container, options) {
    this.container = container;
    this.options = options;
    this.init(0);
}
var p = DropDownListWithMore.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    this.superInit(depth);
    
    if (!this.options) {
        this.options = new Object();
    }
    if (!(this.options.min || this.options.max)) {
        this.options.min = 1;
        this.options.max = 10;
    }
    
    this.defaultValue = 1;
    
    // better to have styling in CSS.
    var cdddl = new CDiv(this);
    //cdddl.setWidth('100');
    //cdddl.setHeight('32');
    cdddl.setFloat('left');
    
    if (this.options.margin) {
        //this.el.style.ma
        this.setStyle('margin', this.options.margin);
    }
    //alert ('this.options.cssFloat ' + this.options.cssFloat);
    if (this.options.cssFloat) {
        this.setFloat(this.options.cssFloat);
    }
    var o = new Object();
    if (this.options.ddlWidth) o.width = this.options.ddlWidth;
    
    var ddl = new DropDownList(cdddl, o);
    //var d = new DropDownList(this);
    ddl.addNumberSequence(this.options.min, this.options.max);
    ddl.add(new AOption({'text':'more', 'value':'more'}));
    ddl.render();
    ddl.onchange = function() {this.container.container.ddl_onchange(); return false; }
    ddl.setStyle('float', 'left');
    //ddl.setWidth('70');
    //d.setHeight('21');
    this.ddlNumPhoneNumbers = ddl;
    
    var t = new IntegerTextBox(this);
    t.setValue('11');
    t.setAlign('right');
    t.setWidth('50');
    //t.setHeight('21');
    
    t.hide();
    
    this.txtNumPhoneNumbers = t;
    
}
p.validate = function() {
    if (this.ddlNumPhoneNumbers.value == 'more') {
        return this.txtNumPhoneNumbers.validate();
    } else {
        return this.ddlNumPhoneNumbers.validate();
    }
}

p.clear = function() {
    // return to initial value
    this.txtNumPhoneNumbers.setValue(11);
    this.txtNumPhoneNumbers.hide();
    
    // clear is to reset to initial value.
    this.ddlNumPhoneNumbers.clear();
    
}

p.setComboBoxWidth = function(value) {
    this.ddlNumPhoneNumbers.setWidth(value);
}

p.ddl_onchange = function() {
    //alert ('ddl_onchange');
    if (this.ddlNumPhoneNumbers.value == 'more') {
        //alert ('more');
        this.txtNumPhoneNumbers.show();
        this.txtNumPhoneNumbers.selectAll();
    } else {
        this.txtNumPhoneNumbers.hide();
    }
    if (this.onchange) this.onchange();
}

//p.setValue = function() {
//    
//}

// need to be able to get the value
p.getValue = function() {
    if (this.ddlNumPhoneNumbers.value == 'more') {
        return this.txtNumPhoneNumbers.getValue();
    } else {
        //alert ('this.ddlNumPhoneNumbers.value ' + this.ddlNumPhoneNumbers.value);
        // I think it does not have a value until it has been rendered into the HTML document.
        if (this.ddlNumPhoneNumbers.value) {
            return this.ddlNumPhoneNumbers.getValue();
        } else {
            if (this.defaultValue) {
                return this.defaultValue;
            }
        }
    }
}

p.setValue = function(value) {
    //alert('DropDownListWithMore setValue value ' + value);
    //alert ('this.options.max ' + this.options.max);
    // search through the list, otherwise select the value with 'more'
    
    // is it greater than the max?
    if (value > this.options.max) {
        this.ddlNumPhoneNumbers.setValue('more');
        this.txtNumPhoneNumbers.setValue(value);
    } else {
        this.ddlNumPhoneNumbers.setValue(value);
        this.ddlNumPhoneNumbers.render();
    }
}


CDValidator = function(container) {
    this.container = container;
    this.init(0);
}
var p = CDValidator.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    this.superInit(depth);
    this.controls = new Array();
    
    this.addMyDiv();
}
// controls then get added inside this.
// validating this validates all of its child controls.

p.addControl = function(control) {
    this.controls.push(control);
    this.el.appendChild(control.el);
}

CDTitleBar = function(container, options) {
    this.container = container;
    this.options = options;
    this.init(0);
}
var p = CDTitleBar.prototype;
p.inheritFrom(CDiv);
p.init = function(depth) {
    this.superInit(depth);
    var oCD = new Object();
    oCD.text = this.options.text;
    this.cdLabel = new CDLabel(this, oCD);
    this.cdLabel.setFloat('none');
    
    this.addMyEl();
}



function createXMLHttp() {
    if (typeof XMLHttpRequest != "undefined") {
        return new XMLHttpRequest();
    } else if (window.ActiveXObject) {
      var aVersions = [ "MSXML2.XMLHttp.5.0",
        "MSXML2.XMLHttp.4.0","MSXML2.XMLHttp.3.0",
        "MSXML2.XMLHttp","Microsoft.XMLHttp"
      ];

      for (var i = 0; i < aVersions.length; i++) {
        try {
            var oXmlHttp = new ActiveXObject(aVersions[i]);
            return oXmlHttp;
        } catch (oError) {
            //Do nothing
        }
      }
    }
    throw new Error("XMLHttp object could not be created.");
}




SoapRequest = function(url, methodName) {
    this.url = url;
    this.methodName = methodName;
    this.initSoapRequest();
}
var p = SoapRequest.prototype;
p.initSoapRequest = function() {
    this.params = new Array();
}

p.send = function(/* Callback */callback) {
    // Need to abstact away the request.
    // Maybe this should use static methods, not from the prototype.

    SoapRequest.send(this, callback);

}
SoapRequest.send = function(soapRequest, callback) {
    var xs = soapRequest.toXmlStr();
    var hr = createXMLHttp();
    //hr.open('post', 'Sessions.asmx', true);
    //alert ('soapRequest.url ' + soapRequest.url);
    //alert ('soapRequest.methodName ' + soapRequest.methodName);

    hr.open('post', soapRequest.url, true);
    hr.setRequestHeader('Content-Type', 'text/xml');
    hr.setRequestHeader('Content-Length', xs.length);
    //hr.setRequestHeader('SOAPAction', 'http://tempuri.org/UserQuery');
    hr.send(xs);

    hr.onreadystatechange = function() {
        if (hr.readyState == 4) {

            //var rx = hr.responseXML;
            //callback.call(hr.responseXML);

            if (callback) callback(hr.responseXML);
        }
    }
}

p.addNewParam = function(name, value) {
    return this.addParam(new SoapRequest.Param(name, value));
}
p.addNewXmlParam = function(xml) {
    return this.addParam(new SoapRequest.XmlParam(xml));
}
p.addParam = function(param) {
    this.params.push(param);
    return param;
}

p.toXmlStr = function() {
    var res = '<?xml version="1.0" encoding="utf-8"?>';
    res = res = '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">';
    res = res + '<soap:Body>';
    res = res + '<' + this.methodName + ' xmlns="http://tempuri.org/">';
    for (var c = 0; c < this.params.length; c++) {
        res = res + this.params[c].toXmlStr();
    }
    res = res + '</' + this.methodName + '>';
    res = res + '</soap:Body>';
    res = res + '</soap:Envelope>';

    return res;
}

p.toXml12Str = function() {
    //var res =  '';
    res = res = '<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">';
    res = res + '<soap12:Body>';
    res = res + '<' + this.methodName + ' xmlns="http://tempuri.org/">';
    for (var c = 0; c < this.params.length; c++) {
        res = res + this.params[c].toXml12Str();
    }
    res = res + '</' + this.methodName + '>';
    res = res + '</soap12:Body>';
    res = res + '</soap12:Envelope>';

    return res;
}

p._type = 'SoapRequest';


// Maybe this will he hooked into XML schema validation functionality.
SoapRequest.Param = function(name, value) {
    this.name = name;
    this.value = value;
}
var p = SoapRequest.Param.prototype;

p.toXml12Str = function() {
    var res = '<' + this.name + '>' + this.value + '</' + this.name + '>';
    return res;
}
p.toXmlStr = function() {
    var res = '<' + this.name + '>' + this.value + '</' + this.name + '>';
    return res;
}

p._type = 'SoapRequest.Param';


SoapRequest.XmlParam = function(xml) {
    this.xml = xml;
}
var p = SoapRequest.XmlParam.prototype;
p.toXmlStr = function() {
    return this.xml;
}
p._type = 'SoapRequest.XmlParam';