/**
 * Class for defining Base control pop-up window
 */

// Base control constructor
// @param string html code of the pop-up window 
// @param object validator: actually for now i have no idea how to implement this thing
BaseControl = function(html, globalErrorMsg, ErrorTitleMsg, validator, actionPrefix, ajaxPage, parentId, javascript) {
    this.Form = null;
    this.actions = {};
    this.ajaxPage = ajaxPage;
    this.actionPrefix = actionPrefix;
    this.Self = this;
    this.setConfig({
        html: html,
        globalErrorMsg: globalErrorMsg,
        errorTitleMsg: ErrorTitleMsg,
        validator: validator,
        parentId: parentId,
        javascript: javascript
    });
    this.extWindow = null; //to be set when modal window is added
    this.fileUploads = [];//to be used for file upload elements (URL/File groups)
};

BaseControl.prototype.modalIndex = 0;

BaseControl.prototype.setConfig = function(config)
{
	this.html = config.html;
	this.globalErrorMsg = config.globalErrorMsg;
	this.errorTitleMsg = config.ErrorTitleMsg;
	this.javascript = config.javascript;
	if (config.validator == null)
	{
	    this.validator = [];
	}
	else
	{
	    if (typeof config.validator == "string")
	    {
	        eval("this.validator = " + config.validator);
	    }
	    else
	    {
	        this.validator = config.validator;
	    }
	}
    if (config.parentId)
    {
        this.controlEl = Ext.get(config.parentId);
    }
}

// Initialization function for base control
BaseControl.prototype.init = function() {
    var validatorsEl = this.controlEl.select('.' + Utils.ControlValidatorsClassName, true);
    if (validatorsEl && validatorsEl.elements[0]) {
        var validators = false;
        var html = validatorsEl.elements[0].dom.innerHTML;
        try {
            eval("validators = " + html);
        }
        catch (e) { }
        if (validators)
            this.InsertValidators(validators);
    }

    var formEl = this.controlEl.select('.extForm', true).elements[0];
    var fileFormEl = this.controlEl.select('.extFormFile', true).elements[0];
    this.Form = new Ext.form.BasicForm(formEl, { submit: function() { return false; }, onSubmit: Ext.emptyFn });
    this.Form.baseCtrl = this;
    this.Form.el.basicForm = this.Form;
    this.Form.close = this.HandeFormClose;
    this.render();

    //add File Uploads:
    rootEls = this.controlEl.select('.' + Utils.ControlFileUploadClassName, true).elements;
    for (var i = 0; i < rootEls.length; i++) {
        if (Utils.AccordingWithParent(rootEls[i], this.controlEl)) {
            this.fileUploads[i] = new FileUpload(rootEls[i], this.Form);
        }
    }
};
BaseControl.prototype.HandeFormClose = function()
{
    var form = this;
    //removing window on close event
    if(form.baseCtrl.controlEl.hasClass(Utils.ControlModalClassName)) {
        BaseControl.prototype.modalIndex--;
    }
    Ext.getBody().setOverflow('auto');
    form.baseCtrl.controlEl.remove();
    form.baseCtrl.controlEl = null;
};
BaseControl.prototype.render = function(root)
{
    if (!root)
    {
        this.Form.items.clear();
        Utils.ParseElements(this.Form); //creating ExtJS elements based on current html. I THINK THAT SECOND PARAMETER HERE MUST BE VALIDATOR...
    }
    else
    {
        Utils.ParseElements(this.Form, root);
    }
    this.Form.render();  //render form to make all validators work
};
BaseControl.prototype.removeContainer = function(root)
{
    if (root != null)
        Utils.RemoveElements(this.Form, root);
};
BaseControl.prototype.setAction = function(action, params)
{	
    var actionName = this.actionPrefix +'_' +  action;
    this.actions[action] = params;
    this.actions[action].name = actionName;
};
BaseControl.prototype.submit = function(options)
{


    if (this.dom.disabled) {
        return false;
    }
    //new functional action_BlahBlah_Event_p0_v0_p1_v1
    var RegExActionName = new RegExp("^action_[a-zA-Z0-9]+_([a-zA-Z0-9]+)");
    var actionEvent = this.dom.name.match(RegExActionName)[1];
    var clsName = Utils.GetControlClassName(this.basicForm.baseCtrl.controlEl);
    if ((typeof (tinyMCE) != "undefined")) {
        for (var i = 0;i < this.basicForm.items.items.length; i++) {
            var formField = this.basicForm.items.items[i];
            if( (formField.getXType() == 'textarea') && (formField.el.hasClass(Utils.ControlWysiwygClassName))) {
                formField.setValue(tinyMCE.get(formField.el.id).getContent())
            }
        }
    }

    if (ControlHandlerRegistrar.CallEvent(clsName, actionEvent, this))
    {
        return true;
    }
/*    
    // Function is implemented on submit event.
    // Attention: this points to Form object but not to base control!!!
    var Form = this.basicForm;
    var FormEl = this.basicForm.el;
    var ControlEl = this.basicForm.baseCtrl.controlEl;

    try
    {
        var elems = ControlEl.select(".extProgress");
        var ProgressEl = Ext.get(elems.elements[elems.elements.length-1]);
    }
    catch (e)
    {
        var ProgressEl = null;
    }
    var RegEx = new RegExp("^action_[a-zA-Z0-9]+_([a-zA-Z0-9]+)");
    var fullActionName = this.dom.name;
    var cmd = this.dom.name.match(RegEx)[1];
    if (cmd == null) {
        alert('This button has no actions!');
    }
    

    
    var action = Form.baseCtrl.actions[cmd];
    var canContinue = true;
    var before_params = null;
    
    if (action.beforecall)
    {
        if (action.beforecallScope)
        {
            var ret = action.beforecall.call(action.beforecallScope);
        }
        else
        {
            var ret = action.beforecall(this);
        }
        if (typeof ret == "object")
        {
            canContinue = ret.canContinue;
            before_params = ret.params;
        }
        else
        {
            canContinue = ret;
        }
    }
    
    if ((action.validate == true) && (canContinue == true) ) {
        var errDiv = null;
        if (Form.baseCtrl.globalErrorMsg != "") {
            divs = FormEl.select(".errorMsg", true); //fetching global message div (this div must have attribute class="errorMsg")
            if (divs.elements.length != 0) {
                errDiv = divs.elements[0].dom;
            } else {
                alert("There are no message divs here!");  // This will implements if any developer can't read comments about attributes
                canContinue = false;
            }
        }    
                
        if (!Form.isValid())  //form validating
        {
            if (action.notValidHandler != null) {
                action.notValidHandler(this);
            }
            canContinue = false;
            
            if (errDiv != null) {
                errDiv.innerHTML = Form.baseCtrl.globalErrorMsg; // error...
                errDiv.style.display = "block";
            }
        } else { //everything ok... 
            if (errDiv != null) {
                errDiv.innerHTML = "";		
                errDiv.style.display = "none";
            }    
        }
    }

    if (canContinue == true)
    {
        if (action.ajax == true) 
        {
           
            if (action.maskAll)
            {
                Ext.getBody().mask();
                ShowGlobalProgress();
            }
            else
            {
                if (ProgressEl != null)
                {
                    ProgressEl.show();
                    ProgressEl.center(FormEl);
                }
                var mask = FormEl.mask();
			    mask.setHeight(FormEl.getHeight());
			    mask.setWidth(FormEl.getWidth());
            }

            var parameters = serializeForm(Form);  //data fetching 
            if ((before_params) && (before_params.length > 0)) {
                parameters += ((parameters.length > 0) ? "&" : "") + before_params;
            }
            
            AjaxProcessor.TimeoutHandler = TimeoutHandler;
            AjaxProcessor.ErrorHandler = TimeoutHandler;
            AjaxProcessor.Request(
                Form.baseCtrl.ajaxPage,
                fullActionName,
                parameters,
                {ctrl: Form.baseCtrl, formEl: FormEl, progressEl: ProgressEl, submitEl: this}
            );
            
            return true;
        }
        else
        {
            this.dom.form.submit();
        }
    }*/
};

BaseControl.prototype.InsertValidators = function (sourceValidators)
{
    /// examining validators
    for (var i = 0; i < sourceValidators.length; i++)
    {
        var exist = false;
        var sourceValidator = sourceValidators[i];
        for (var j = 0; j < this.validator.length; j++){
            var destValidator = this.validator[j];
            if(destValidator.name == sourceValidator.name){
            
                /// examining validatorParts
                for (var ii = 0; ii < sourceValidator.validatorParts.length; ii++){
                    var partExist = false;
                    for (var jj = 0; jj < destValidator.validatorParts.length; jj++)
                        if(sourceValidator.validatorParts[ii].type == destValidator.validatorParts[jj].type){
                            //replace on new part
                            destValidator.validatorParts[jj] = sourceValidator.validatorParts[ii];
                            partExist = true;
                            break;
                        }
                    if(!partExist)// part is not exist - then copy
                        destValidator.validatorParts[destValidator.validatorParts.length] = sourceValidator.validatorParts[ii];
                }

                exist = true;
                break;
            }
        }
        if(!exist) // validator is not exist - then copy
            this.validator[this.validator.length] = sourceValidators[i];
    }
};

BaseControl.prototype.GetValidator = function (elDom)
{
    var elName;
    if (typeof elDom == 'string')
    { 
        elName = elDom;
    }
    else
    {
        elName = elDom.name;
    }
    
    var regEx = new RegExp("^[A-Za-z0-9]*");
            
    for (var i = 0; i < this.validator.length; i++)
    {
       if (this.validator[i].name == elName.match(regEx))
        {
            return this.validator[i];
        }
    }
    
    return null;
};

BaseControl.prototype.destroy = function() {
    var i;
    var el;
    for (i = 0; i < this.Form.items.items.length; i++) {
        if (this.Form.items.items[i].isXType('textarea')) {
            el = this.Form.items.items[i].el;
            if ((typeof (tinyMCE) != "undefined") && (el.hasClass(Utils.ControlWysiwygClassName))) {
                tinyMCE.execCommand("mceRemoveControl", true, el.dom.id);
            }
        }
    }

    for (i in this.Form.items.items) {
        this.Form.remove(this.Form.items.items[i]);
    }

    Ext.destroy(this.Form);
    Ext.destroy(this.controlEl);

    if (this.extWindow != null) {
        //Ext.WindowMgr.sendToBack(Ext.WindowMgr.getActive())
        Ext.WindowMgr.sendToBack(this.extWindow);
    }
    Ext.destroy(this.extWindow);

    for (i = 0; i < this.fileUploads.length; i++) {
        Ext.destroy(this.fileUploads[i]);
        delete this.fileUploads[i];
    }

    this.Form.baseCtrl = null;
    this.Self = null;

    for (i in this) {
        delete this[i];
    }

};

//Static Methods:
BaseControl.Mask = function(FormEl) {
    var elToMask = FormEl.select('.extMask', true).elements[0];
    if (elToMask != null) {
        elToMask.mask();
    } else {
        FormEl.mask();
    }

    var inps = FormEl.select("input[type=submit]").elements;
    for (var i = 0; i < inps.length; i++) {
        inps[i].disabled = true;
    }
}

function getControlByClassName(className) {
    var ctrl = Ext.select(className, true).elements[0];
    return ControlManager.Get(ctrl.id);
}

function getFieldByNameForControl(ctrl, fieldName) {
    var els = ctrl.controlEl.select('input[name^=' + fieldName + ']').elements;
    if (els.length == 0) {
        return null;
    }
    return ctrl.Form.findField(els[0].name);
}

function serializeForm (form)
{
    var el, name, val, disabled, data = '', hasSubmit = false;
    var dataArr = {};
    
    var nItemsCount = form.items.getCount();
    for (var i = 0; i < nItemsCount; i++)
    {
        el = form.items.item(i);
        if (el != null)
        {
            if (el.ctype != null && el.ctype == 'Ext.Component')
            {
                if (!el.disabled)
                {
                    name = el.getName();
                    if (el.isXType('datefield')) { //fix for ALC
                        val = el.getRawValue();
                    } else {
                        val = el.getValue();
                    }
                    if (name) {
                        if (dataArr[name] == null) {
                            dataArr[name] = val;
                            data += encodeURIComponent(name) + '=' + encodeURIComponent(val).replace('_', '%5F') + '&';
                        }
                    }
                }
            }
        }
    }
    data = data.substr(0, data.length - 1);
    return data;
};
function TimeoutHandler(duration, res)
{
    //Stop request
    if (res.abort)
        res.abort();
        
    if (AjaxProcessor)    
    {
        var context = AjaxProcessor.GetContext(res.args.id);
        if (context)   
        {
            if (context.progressEl)
                context.progressEl.hide();
            if (context.formEl)
            {    
                context.formEl.unmask();
                context.formEl.show();
            }
            if (ControlTimeoutError)
            {
                ControlTimeoutError.show();
            }
        }
    }
};
function AddGlobalProgress()
{
    var html = "<div class='" + Utils.ControlGlobalProgressClassName + "' style='height:25px;display:none; text-align: center;'>Loading...</div>"
    var el = Ext.DomHelper.append(document.body, html, true);
};
function ShowGlobalProgress()
{
    bodyEl = Ext.get("body");
    var divs = bodyEl.select("." + Utils.ControlGlobalProgressClassName);
    if(divs.elements)
    {
        Ext.get(divs.elements[0]).show();
        Ext.get(divs.elements[0]).center(bodyEl);
    }
};
function HideGlobalProgress()
{
    bodyEl = Ext.get("body");
    var divs = bodyEl.select("." + Utils.ControlGlobalProgressClassName);
    if(divs.elements)
    {
        Ext.get(divs.elements[0]).hide();
    }
};