﻿var morphManager =
{
    activeInput: null,
    imageBaseUrl: 'Images/Icons/',
    defaultMorph: 'Morphix1',
    defaultNearness: false,
    defaultNearWordCount: 3,
    toggledOn: false,
    mainRadioPrefix: 'ctl00_mainContentPlaceHolder_morphSelect_morphTypesRadioList_',
    mainRadioDefaultSuffix: '_0',
    
    mainNearValueText: "ctl00_mainContentPlaceHolder_morphSelect_nearValueText",
    popupNearValueText: "ctl00_nearValueText",
    mainNearValueBlock: "ctl00_mainContentPlaceHolder_morphSelect_nearValueBlock",
    popupNearValueBlock: "ctl00_nearValueBlock",
    mainNearSelect: 'ctl00_mainContentPlaceHolder_morphSelect_nearTypeCombo',
    popupNearSelect: 'ctl00_nearTypeCombo',
    
    nearSelectOptions:
    {
        Near: 1,
        Next: 0
    },

    inputGroups:
    {
        AllWords: { inputs: [], selectable: true },
        AnyWords: { inputs: [], selectable: true },
        ExactWords: { inputs: [], selectable: false },
        ExcludedWords: { inputs: [], selectable: true }
    },

    morphTypes:
    {
        Inherit: { image: '', code: 0, selectName: '' },
        MorphixExact: { image: 'morphix_exact.gif', code: 5, selectName: 'ctl00_morphTypesRadioList_4' },
        Morphix1: { image: 'morphix_morph.gif', code: 6, selectName: 'ctl00_morphTypesRadioList_0' },
        MorphixExtended: { image: 'morphix_expanded.gif', code: 7, selectName: 'ctl00_morphTypesRadioList_2' },
        MorphixSynonyms: { image: 'morphix_syn.gif', code: 8, selectName: 'ctl00_morphTypesRadioList_1' },
        MorphixPrefixes: { image: 'morphix_prefix.gif', code: 9, selectName: 'ctl00_morphTypesRadioList_3' }

    },


    Init: function(radioPrefix) {
        //        morphManager.morphTypes.MorphixPrefixes.selectName = morphixPrefixesSelectId;
        //        morphManager.morphTypes.Morphix1.selectName = morphix1SelectId;
        //        morphManager.morphTypes.MorphixExtended.selectName = morphixExtendedSelectId;
        //        morphManager.morphTypes.MorphixSynonyms.selectName = morphixSynonymsSelectId;
        //        
        //        morphManager.nearSelectOptions.Near = nearSelectId;
        //        morphManager.nearSelectOptions.Next = nextSelectId;

        morphManager.mainRadioPrefix = radioPrefix;
        //        morphManager.mainRadioDefaultSuffix = radioDefaultSuffix;
    },

    GetSpan: function(baseId) {
        return document.getElementById(baseId + '_span');
    },

    // Registers a morphInput with the morphManager and assigns it to the specified group
    Register: function(baseId, inputId, morphType, wordGroup, divNumber) {
        morphManager.inputGroups[wordGroup].inputs.push(new MorphInput(baseId, inputId, morphType, morphManager.inputGroups[wordGroup].selectable));
    },

    // Hides/shows all morph-images for all morphInputs (in all the inputGroups)
    ToggleMorphs: function() {
        for (var groupName in morphManager.inputGroups) {
            var isGroupSelectable = morphManager.inputGroups[groupName].selectable;
            var inputGroup = morphManager.inputGroups[groupName].inputs;

            for (var i = 0; i < inputGroup.length; i++) {
                inputGroup[i].ToggleMorph(isGroupSelectable);
            }
        }

        morphManager.toggledOn = !morphManager.toggledOn;
    },

    SetActiveMorphInput: function(morphInput) {
        morphManager.activeInput = morphInput;
    },

    ChangeMorph: function(morphType) {
        if (morphManager.activeInput) {
            //close tip if it was open
            $j('#cluetip')[0].style.display = 'none';

            morphManager.activeInput.SetMorphType(morphType);
        }
    },

    ChangeMorphByCode: function(morphTypeCode) {
        var morphType = morphManager.GetMorphIdByCode(morphTypeCode);
        morphManager.ChangeMorph(morphType);
    },

    GetMorphIdByCode: function(code) {
        var result = morphManager.morphTypes.Inherit;
        for (var morphName in morphManager.morphTypes) {
            if (morphManager.morphTypes[morphName].code == code) {
                result = morphName;
            }
        }
        return result;
    },

    SetAllMorphs: function(morphType, clearNears) {
        morphManager.defaultMorph = morphType;
        morphManager.ResetAllMorphs(clearNears);
    },

    ResetAllMorphs: function(clearNears) {
        for (var groupName in morphManager.inputGroups) {
            if (morphManager.inputGroups[groupName].selectable) {
                for (var inputIndex in morphManager.inputGroups[groupName].inputs) {
                    morphManager.SetActiveMorphInput(morphManager.inputGroups[groupName].inputs[inputIndex]);
                    morphManager.ChangeMorph(morphManager.defaultMorph);
                    if (clearNears) {
                        morphManager.activeInput.isNear = false;
                    }
                }
            }
        }
    },

    //sets all fields in form for nearness type
    SetAllNearTypes: function(isNearValue, nearWordCount) {
        morphManager.defaultNearness = isNearValue;
        morphManager.defaultNearWordCount = nearWordCount;

        for (var groupName in morphManager.inputGroups) {
            if (morphManager.inputGroups[groupName].selectable) {
                for (var inputIndex in morphManager.inputGroups[groupName].inputs) {
                    morphManager.SetActiveMorphInput(morphManager.inputGroups[groupName].inputs[inputIndex]);
                    morphManager.ChangeNearType(isNearValue, nearWordCount);
                }
            }
        }

        $j("[id$=" + morphManager.mainNearValueBlock + "]")//.attr("disabled", isNearValue ? "" : "disabled");
                .attr("class", isNearValue ? "shownPanel" : "hiddenPanel");
    },
                
    //changes isNear for field (true or false)
    ChangeNearType: function(isNearValue, nearWordCount) {
    $j("[id$=" + morphManager.popupNearValueBlock + "]")//.attr("disabled", isNearValue ? "" : "disabled");
                .attr("class", isNearValue ? "shownPanel" : "hiddenPanel");
        morphManager.activeInput.ChangeIsNear(isNearValue, nearWordCount);
    },

    //clears morphology back to default
    ClearAll: function() {
        morphManager.SetAllMorphs('Morphix1', true);
        $j("[id$=" + morphManager.mainNearValueText + "]")
            .val('3');

        morphManager.SetAllNearTypes(false, 3);
        morphManager.ClearMainRadio();

        if (morphManager.toggledOn) {
            morphManager.ToggleMorphs();
        }
    },

   

    //clears the main morph radio buttons
    ClearMainRadio: function() {
        var $radios = $j('input[@id^=' + morphManager.mainRadioPrefix + ']');

        for (i = 0; i < $radios.length; i++) {
            if ($radios[i].id == morphManager.mainRadioPrefix + morphManager.mainRadioDefaultSuffix) {
                $radios[i].checked = true;
            }
            else {
                $radios[i].checked = false;
            }
        }
    }
};

// The class that encapsulates a single morph-input together with its span and hidden-input
// param "morphType": One of the morphManager.morphTypes with which to initialize the MorphInput
function MorphInput(baseId, inputId, morphType, selectable) {
    //
    // private members
    //
    var image = document.getElementById(baseId + '_img');
    //var hidden = document.getElementById(baseId + '_hidden');
    this.currentMorphType = morphType;

    this.isNear = false;

    this.distribution = 50;

    var Init = function(ref) {
        ref.SetMorphType(morphType);

        // initialize popups
        $j(image).cluetip({
            width: 215,
            closeText: '<img src="Images/close_rss.gif" alt="סגור" />',
            cluetipClass: 'koldin',
            closePosition: 'title',
            showTitle: false,
            positionBy: 'bottomTop',
            arrows: true,
            ajaxCache: false,
            ajaxProcess: function(data) {
                // Parse content out of xml
                return $j(data).find('string').text();
            },
            ajaxSettings: {
                dataType: 'xml'
            },
            //on show, adjust radio buttons to current selection
            onShow: function(ct, c) {
                ref.MakeControlSelections();
            }

        })
        .click(function() {
            morphManager.SetActiveMorphInput(ref);
        });

        // Fix IE6 combo-box z-index problem
        $j('#cluetip').bgiframe();
    };

    //
    // public members
    //
    this.input = document.getElementById(inputId);

    this.GetClientString = function() {
        var inputValue = this.input.value;
        inputValue = inputValue.replace(/[\{\}]/g, '');

        if (/\S+/.test(inputValue)) //check that the string contains non-space chars
        {
            return "{" +
                utility.TrimString(inputValue) +
                "}[m" + morphManager.morphTypes[this.currentMorphType].code + "]" +
                (this.isNear ? "[d" + this.distribution + "]" : "");
        }
    };

    this.SetMorphType = function(morphType) {
        this.currentMorphType = morphType;
        image.src = morphManager.imageBaseUrl + morphManager.morphTypes[morphType].image;

        //no near for exact searches
        if (this.currentMorphType == "MorphixExact") {
            this.ChangeIsNear(false);
        }
    };

    // Show/Hide the morph-span
    this.ToggleMorph = function(isSelectable) {
        if (!isSelectable) {
            image.style.display = 'none';
        }
        else if (image.style.display != 'none') {
            image.style.display = 'none';
        }
        else {
            image.style.display = '';
        }
    };

    //set field as "near"
    this.ChangeIsNear = function(isNearValue, nearWordCount) {
        //no near for exact searches
        if (this.currentMorphType == "MorphixExact") {
            this.isNear = false;
        }
        else {
            this.isNear = isNearValue;
        }

        if (this.isNear) {
            this.ChangeInputTextToNear(nearWordCount);
            //this.input.onblur = function(){morphManager.ChangeNewInputTextToNear(this.);};
        }
        else {
            this.ChangeInputTextToNext(nearWordCount);
            //this.input.onblur = function(){};
        }
    };

    //replace all spaces in text with [ק]
    this.ChangeInputTextToNear = function(count) {
        //this.input.value = this.ProcessNearField(this.input.value, count);
        if (count) {
            this.distribution = count;
        }
    };

    //    this.ProcessNearField = function(fieldValue, count)
    //    {
    //        //        var spaceRegEx = / +/g;
    //        //        var nearRegEx = / *\[ק\] */g;
    //        //        var doubleNearRegEx = / *\[ק\] *\[ק\] */g;

    //        var token = useLucene ? ((count ? count : "")) : "ק";

    //        var spaceRegEx = new RegExp(" +", useLucene ? "" : "g");
    //        var nearRegEx = new RegExp(" *\\[" + token + "\\] *", useLucene ? "" : "g");
    //        var doubleNearRegEx = new RegExp(" *\\[" + token + "\\] *\\[" + token + "\\] *", useLucene ? "" : "g");

    //        //        fieldValue = fieldValue.replace(nearRegEx, "[ק]");
    //        //        fieldValue = fieldValue.replace(doubleNearRegEx, "[ק]");
    //        //        fieldValue = utility.TrimString(fieldValue).replace(spaceRegEx, "[ק]");
    //        //        fieldValue = fieldValue.replace(nearRegEx, " [ק] ");
    //        fieldValue = fieldValue.replace(nearRegEx, "[" + token + "]");
    //        fieldValue = fieldValue.replace(doubleNearRegEx, "[" + token + "]");
    //        fieldValue = utility.TrimString(fieldValue).replace(spaceRegEx, "[" + token + "]");
    //        fieldValue = fieldValue.replace(nearRegEx, " [" + token + "] ");
    //        return fieldValue;
    //    };

    //replace all [ק] in text with spaces
    this.ChangeInputTextToNext = function(count) {
        this.distribution = 50;
    };

    //select cluetip's controls according to morphInput's current settings
    this.MakeControlSelections = function() {
        this.SelectMorphRadioButton();
        this.SelectNearComboItem();
    };

    //select morphType radio button according to morphType
    this.SelectMorphRadioButton = function() {
        var morphSelectName = morphManager.morphTypes[this.currentMorphType].selectName;
        if (morphSelectName != null) {
            var morphSelect = document.getElementById(morphSelectName);
            morphSelect.checked = true;
        }
    };

    //select near combo item according to isNear
    this.SelectNearComboItem = function() {
        var selectedOptionIndex;
        var unselectedOptionIndex;

        if (this.isNear) {
            selectedOptionIndex = morphManager.nearSelectOptions.Near;
            unselectedOptionIndex = morphManager.nearSelectOptions.Next;

            // set near visibility
            $j("[id$=" + morphManager.popupNearValueBlock+ "]")
            //.attr("disabled", "")
                .attr("class", "shownPanel");
            
            // set near value
            $j("[id$=" + morphManager.popupNearValueText + "]")
                .val(this.distribution);

        }
        else {
            selectedOptionIndex = morphManager.nearSelectOptions.Next;
            unselectedOptionIndex = morphManager.nearSelectOptions.Near;

            $j("[id$=" + morphManager.popupNearValueText + "]")
                .val(morphManager.defaultNearWordCount);
        }



        //        if (selectedOptionIndex != '') {
        //            var checkedSelect = document.getElementById(selectedOptionIndex);
        //            checkedSelect.Selected = true;
        //        }
        var nearCombo = document.getElementById(morphManager.popupNearSelect);
        nearCombo.options[selectedOptionIndex].selected = true;
        
        //disable near radio buttons if morph type is exact (this should neer happen)
        //  if (this.currentMorphType == "MorphixExact") {
        //      checkedSelect.disabled = true;
        //      if (selectedOptionIndex != '') {
        //          var uncheckedSelect = document.getElementById(unselectedOptionIndex);
        //          uncheckedSelect.disabled = true;
        //      }
        //  }
    };

    // CONSTRUCTOR CALL
    Init(this);

    //show image if morph is toggled on
    if (morphManager.toggledOn && image.style.display == 'none') {
        this.ToggleMorph(selectable);
    }
}