﻿/// <reference path='/Home/TextJS' />
/// <reference path='http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js' />
/// <reference path='jquery/jquery-ui.min.js' />
/// <reference path='jquery/jquery.hoverIntent.min.js' />
/// <reference path='jquery/jquery.json.min.js' />
/// <reference path='jquery/jquery.translate-core.min.js' />
/// <reference path='jquery/jquery.cookie.min.js' />
/// <reference path='http://www.google.com/uds/api?file=uds.js&v=1.0' />
/// <reference path='http://www.google.com/uds/api/search/1.0/c79ce868b02751bfaa50db2af590d055/default+en.I.js' />

//report errors
window.onerror = function () {
    //todo: report this back to the server
};

//global behavior variables
var generalCount = 20;
var firstSectionCount = 3;
var minSearchLength = 2;
var sectionResultsMaxHeight = 13 * firstSectionCount;

var wikiCSE = { es: '015858065107119372244:vldq9ouzoko', en: '015858065107119372244:8jfwfhi7y0e', fr: '015858065107119372244:te70qgqn45c', de: '015858065107119372244:puprjir-oce', it: '015858065107119372244:ce_nr_-idwm' };
var cochraneCSE = { en: '015858065107119372244:5qo-y0rjfrw', fr: '015858065107119372244:5qo-y0rjfrw', de: '015858065107119372244:z9suchq2ap0', it: '015858065107119372244:pk5yipgqe44', es: '015858065107119372244:yqjdpo1smls' };
var cochraneTranslate = lang == 'fr';
var googleExcludeAppend = ' -site:' + ['www.ncbi.nlm.nih.gov', 'www.cochrane.org', 'www.webmd.com', 'clinicaltrials.gov', 'centerwatch.com', 'Clinicalstudyresults.Org',
                                        'cancer.gov', 'nice.org.uk', 'roche-trials.com'].join(' -site:'); //'wikipedia.org', 'twitter.com', 

var googleSourceFormat = { searchFormat: 'google', maxCount: 8, translate: false, enabled: true, multiSection: false, restrictLang: true, append: '' };

window.sources =
    [{ name: 'Drugs', searchFormat: 'medtango', maxCount: generalCount, translate: false, enabled: true, multiSection: true }
   , { name: 'Interactions', searchFormat: 'medtango', maxCount: generalCount, translate: false, enabled: true, multiSection: true }
   , { name: 'Disease', searchFormat: 'medtango', maxCount: generalCount, translate: false, enabled: true, multiSection: true }
//, { name: 'Clinical', searchFormat: 'Clinical', maxCount: generalCount, translate: true, enabled: true, multiSection: false }
   , { name: 'Clinical', searchFormat: 'google', maxCount: 10, translate: true, enabled: true, multiSection: false, restrictLang: false, cse: '015858065107119372244:e2uctngb09q' }
   , { name: 'News', searchFormat: 'google', maxCount: 10, translate: true, enabled: true, multiSection: false, restrictLang: false, cse: '015858065107119372244:f-evmnjccti' }
   , { name: 'PubMed', searchFormat: 'google', maxCount: 10, translate: lang == 'es' ? false : true, enabled: true, multiSection: false, restrictLang: false, cse: lang == 'es' ? '015858065107119372244:jcqnd5u7mfa' : '015858065107119372244:4oaqmtwedda' }
   , { name: 'Cochrane', searchFormat: 'google', maxCount: 10, translate: cochraneTranslate, enabled: true, multiSection: false, restrictLang: false, cse: cochraneCSE[lang] }
   , { name: 'WebMD', searchFormat: 'google', maxCount: 10, translate: true, enabled: true, multiSection: false, restrictLang: false, cse: '015858065107119372244:sdwncfneh8u' }
   , { name: 'Pharmaceuticals', searchFormat: 'google', maxCount: 10, translate: true, enabled: true, multiSection: false, restrictLang: false, cse: '015858065107119372244:0w1o-ihz2um' }
   //, { name: 'Wiki', searchFormat: 'google', maxCount: 10, translate: false, enabled: false, multiSection: false, restrictLang: false, cse: wikiCSE[lang] }
   , $.extend({ name: 'Web' }, googleSourceFormat)
   //, { name: 'Twitter', searchFormat: 'twitter', translate: false, maxCount: generalCount, enabled: false, multiSection: false }
    ];

function prepareSources() {
    if (lang == 'fr') {
        //cismef cse taken from their site
        sources[sources.length] = { name: 'Cismef', searchFormat: 'google', maxCount: 10, translate: false, enabled: true, multiSection: false, restrictLang: true, cse: '015430007758165987576:navgp85jvic' };
        sources[sources.length] = { name: 'CNRSInist', searchFormat: 'google', maxCount: 10, translate: false, enabled: true, multiSection: false, restrictLang: false, cse: '015858065107119372244:d3qnddo6efg' };
    }
    if (lang == 'en' && location.host.match('localhost|\\.(com|co\\.uk)$'))
        sources[sources.length] = { name: 'DailyMed', searchFormat: 'medtango', maxCount: generalCount, translate: false, enabled: true, multiSection: true, restrictLang: false };

    //reorder the items added to the sources list
    var langOrder = {
        fr: ['Drugs', 'Interactions', 'Disease', 'Cismef', 'News', 'CNRSInist'],
        en: ['Drugs', 'DailyMed', 'Interactions', 'Disease']
    };

    if (langOrder[lang]) {
        var lngCnt = 0;
        $.each(langOrder[lang], function (i, sourceName) {
            var matches = $.grep(sources, function (source) { return source.name == sourceName });
            if (matches.length == 1) {
                var index = $.inArray(matches[0], sources);
                sources.splice(lngCnt, 0, sources.splice(index, 1)[0]);
                lngCnt++;
            }
        });
    }

    $.each(sources, function (i, source) { source.header = sourceHeaders[source.name]; });

    //if we have saved order then reorder sources and append new ones
    if (dbSources) {
        //iterate through the cached sources and return back a list to replace the window.sources
        var reorderedSources = $.map(dbSources, function (cache, i) {
            //it's custom, so append the url exclusion list to the url restriction
            if (cache.custom)
                return newSourceCategory(cache.header, cache.customUrl, cache.enabled);

            //it's standard, get the item and set it up
            var source = $.grep(sources, function (source) { return source.name == cache.name; });
            if (source.length == 1)
                return $.extend(source[0], { enabled: cache.enabled == "true" });

            //it's standard but has been removed from the list
            return null;
        });
        
        //in case there are new standard sources not stored in the cache
        var newSources = $.grep(sources, //find sources that are not contained in the reorderedSources list
                function (source) { return $.grep(reorderedSources, function (newSource) { return newSource.name == source.name; }).length == 0; });
        $.each(newSources, function (i, source) { source.enabled = true; });

        window.sources = $.merge(reorderedSources, newSources);
    }
}

//convert sourcesToSearch to a number array
function setSourcesToSearch(moreSources) {
    window.sourcesToSearch = $.map($.merge(['News', 'Clinical', 'WebMD'], moreSources),
                                    function (sourceName) {
                                        for (var y = 0; y < sources.length; y++)
                                            if (sources[y].name == sourceName)
                                                return y;
                                    });
}

$(document).ready(function () {
    prepareSources();

    if ($.cookie('changingLanguage') == 'true')
        $.cookie('changeLanguage', null, { expires: 365 });
});

function getSearchText() {
    return $.trim($('#searchText').val().replace(splitRegex, ' or ').replace(/\sor\sor\s/ig, ' or ')).replace(/\s\s/g, ' ');
}

function changeLanguage(item) {
    var domain = item.lang ? item.lang : item.attr('lang');
    $.cookie('changeLanguage', domain, { expires: 365 });
    if (domain == 'en')
        domain = 'com';
    document.location.replace('http://www.medtango.' + domain + document.location.pathname + document.location.search +
                                    (document.location.search.indexOf('?') == -1 ? '?' : '&') + 'changeLanguage=1');
}

function dailymedFix(label, identifier, lastUpdated) {
    var imgFolder = '/DailyMed/' + lastUpdated + '_' + identifier + '/';
    $('img', label).each(function (i, img) { img = $(img); img.attr('src', imgFolder + img.attr('src')); });

    $('table[class="textHighlights"]', label).before($('<a/>').attr('name', 'nlmhighlights'));

    $('*[class="toc"]', label).before($('<a/>').attr('name', 'nlmftoc'));
}

function jsonSources() {
    var sourcesArr = [];
    $.each(sources, function (i, source) { sourcesArr[i] = source; });
    return $.toJSON({ sources: { source: sourcesArr} });
}

function signOut() {
    $.ajax({
        url: '/Home/SignOut',
        success: function (auth) { location.reload(); },
        error: function () { alert(errorResultsText); }
    });
}

function showAuthenticate() {
    _showAuthenticate();
    $('#authenticationDialog').validate({ submitHandler: sendAuthentication, focusInvalid: false, wrapper: 'div',
        rules: { email: 'required email', password: 'required' }
    }).resetForm();
}
function showForgotPassword() {
    _showForgotPassword();
    $('#forgotPasswordDialog').validate({ submitHandler: sendForgotPassword, focusInvalid: false, wrapper: 'div',
        rules: { email: 'required email' }
    }).resetForm();
}
function showRegistration() {
    _showRegistration();

    var select = $('#registrationDialog select[name="specialty"]')[0];
    if (select.options.length == 1) {
        $.ajax({
            url: '/Home/GetJBTITList',
            data: { lang: lang, id: 0 },
            type: 'POST',
            success: function (data) {
                $($.map(data, function (item) {
                    return $('<option/>').attr('value', item.ID).text(item.Title);
                })).appendTo(select);
            },
            error: function () { alert(errorResultsText); }
        });

        //not firing in ie on key up/down press (http://dev.jquery.com/ticket/6877)
        $(select).change(function () {
            var method = populateSpecialtyMethod();
            if (select.value)
                $.ajax({
                    url: '/Home/GetJBTITList',
                    data: { lang: lang, id: select.value },
                    type: 'POST',
                    success: method,
                    error: function () { alert(errorResultsText); }
                });
        });
    }

    $('#registrationDialog').validate({ submitHandler: sendRegistration, focusInvalid: false, wrapper: 'div',
        rules: { email: 'required email', password: { required: true, minlength: 6 }, first: 'required',
            last: 'required', jbtit: 'required', specialty: 'required', privatePractice: 'required'
        },
        errorPlacement: function (error, element) {
            if (element.attr("name") == "jbtit" || element.attr("name") == "privatePractice")
                error.insertBefore(element);
            else error.insertAfter(element);
        }
    }).resetForm();
}
function addCategory() {
    if (userEmail)
        addCategoryDialog();
    else {
        alert(signin.restrictedFeature);
        showAuthenticate();
    }
}
function addCategoryDialog(sourceIndex) {
    _addCategoryDialog(sourceIndex);
    $('#categoryAddDialog').data('sourceIndex', sourceIndex ? sourceIndex : null).validate({
        submitHandler: function () { sendAddCategory($('#categoryAddDialog').data('sourceIndex')); },
        focusInvalid: false, wrapper: 'div', rules: { name: 'required', url: 'required' }
    }).resetForm();

    $('#categoryAddDialog').find('input').val('');
    if (sourceIndex)
        $('#categoryAddDialog').find('input[name=name]').val(sources[sourceIndex].header).end()
                                .find('input[name=url]').val(sources[sourceIndex].customUrl);
}
function sendAuthentication() {
    var form = $('#authenticationDialog')[0];
    $.ajax({
        url: '/Home/AuthenticateUser',
        data: { email: $.trim(form.email.value), password: $.trim(form.password.value), remember: form.rememberMe.checked, settings: jsonSources() },
        type: 'POST',
        success: function (auth) {
            if (auth)
                location.reload();
            else
                alert(signin.authFail);
        },
        error: function () { alert(errorResultsText); }
    });
}
function sendForgotPassword() {
    var form = $('#forgotPasswordDialog')[0];
    $.ajax({
        url: '/Home/ForgotPassword',
        data: { email: $.trim(form.email.value) },
        type: 'POST',
        success: function (emailFound) {
            if (emailFound) {
                //$('#forgotPasswordDialog').dialog('close');
                alert(signin.passwordEmailed);
            }
            else
                alert(signin.emailNotFount);
        },
        error: function () { alert(errorResultsText); }
    });
}
function sendRegistration() {
    var form = $('#registrationDialog')[0];
    $.ajax({
        url: '/Home/RegisterUser',
        data: { email: $.trim(form.email.value), password: $.trim(form.password.value),
            first: $.trim(form.first.value), last: $.trim(form.last.value),
            jbtit: $('input[name="jbtit"]:checked')[0].value.replace('_', ''), //_ sencha bug
            privatePractice: eval($(':radio:checked', form).val()), settings: jsonSources()
        },
        type: 'POST',
        success: function (registered) {
            if (registered)
                location.reload();
            else {
                //$('#registrationDialog').dialog('close');
                alert(signin.alreadyRegistered + '  ' + signin.passwordEmailed);
            }
        },
        error: function () { alert(errorResultsText); }
    });
}
function sendAddCategory(sourceIndex) {
    if (!sourceIndex)
        sourceIndex = sources.length;

    //add the new source item, save it to cookies, then reload the page
    var form = $('#categoryAddDialog')[0];
    sources[sourceIndex] = newSourceCategory($.trim(form.name.value), $.trim(form.url.value), true);
    $.ajax({
        url: '/Home/SaveUserSettings',
        data: { settings: jsonSources() },
        type: 'POST',
        success: function () { location.reload(); },
        error: function () { alert(errorResultsText); }
    });
}

function confirmDelete(sourceIndex) {
    if (!confirm(categories.deleteConfirm))
        return;
    sources.splice(sourceIndex, 1);
    setCookieCategories(function () { location.reload(); });
}

function setCookieCategories(func) {
    window.dbSources = sources;
    $.ajax({
        url: '/Home/SaveUserSettings',
        data: { settings: jsonSources() },
        type: 'POST',
        success: func,
        error: function () { alert(errorResultsText); }
    });
}

function newSourceCategory(header, url, enabled) {
    //give it a custom name
    return $.extend({}, googleSourceFormat,
        { name: 'cache' + Math.random().toString().replace('.', '_'), header: header, customUrl: url, enabled: enabled, append: ' site:' + url, custom: true });
}

//google auto-complete
var googleSuggest = null;
//my autocomplete
function autoCompleteMethod(request, response) {
    //store the current term and close it, so if its showing for 'wor' and 'work' takes a long time, 'wor' won't stay up
    closeAutoComplete();

    var term = $('#searchText').val();
    $('#searchText').data('term', term);
    
    if (term.length < minSearchLength) {
        response([]);
        return;
    }
    
    var bIncludeGoogle = term.length > 2;
    googleSuggest = null;
    var finish = function () {
        if ($('#searchText').data('term') != term)
            return;

        if (bIncludeGoogle) {
            if (googleSuggest == null) {
                setTimeout(finish, 10);
                return;
            }
            //join my suggestions with googles, excluding duplicates
            var uniqueG = $.grep(googleSuggest[1], function (g) {
                return $.grep(mySuggest, function (s) {
                    return g[0].toLowerCase() == s.label.toLowerCase()
                }).length == 0;
            });
            $.merge(mySuggest, $.map(uniqueG, function (g) { return { label: g[0], value: g[0] }; }));
        }

        //pass the final list to the autocomplete results processor
        if ($('#searchText').data('searching'))
            response(mySuggest);
    };
    var mySuggest = [];

    if (bIncludeGoogle)
        $.ajax({
            url: 'http://www.google.com/complete/search',
            data: { hl: lang, qu: term },
            dataType: 'jsonp',
            success: function (data) {
                //only reset suggestions if the search text is currently the callback
                if ($('#searchText').data('term') == data[0])
                    googleSuggest = data;
            }
        });

    var terms = (getSearchText() + ' ').split(' or ');
    if ($.trim(terms[terms.length - 1]).length < minSearchLength)
        finish();
    else
        $.ajax({
            url: '/Home/GetWords',
            data: { prefix: term, count: bIncludeGoogle ? 10 : 20 },
            type: 'POST',
            context: { term: term }, //http://dev.jquery.com/ticket/6727
            //transform the returned list into autocomplete items
            success: function (data) {
                //don't override current auto-complete if this is an old request
                if (this.term != $('#searchText').data('term'))
                    return;
                mySuggest = data;
                finish();
            }
        });
}

function setResultsDivData(searchTerm) {
    //add some extra data to the element for future checking
    $('#resultsDiv').data({ search: searchTerm, time: new Date().getTime(),
        //add an array to track the current page of each search
        pages: $.map(sources, function () { return 1; })
    });
}

function trackSearch() {
    $.ajax({
        url: '/Home/TrackSearch',
        data: { searchText: $('#resultsDiv').data('search') },
        type: 'POST'
    });
}

//search methods
function _executeSearch(sourceIndex, page, bTrackSearch) {
    var source = sources[sourceIndex];
    var resultsDiv = $('#resultsDiv');
    var val = resultsDiv.data('search');
    resultsDiv.data('pages')[sourceIndex] = page;

    if (source.searchFormat == 'twitter')
        $.ajax({
            url: 'http://search.twitter.com/search.json',
            data: { q: val, rpp: source.maxCount, page: page, lang: lang },
            context: { sourceIndex: sourceIndex, query: val },
            dataType: 'jsonp',
            success: function (data) {
                if (data.error != null) appendError(this.sourceIndex);
                else {
                    //loop through results, modifying each one with extend method, and set title to plain text
                    var results = $.map(data.results, function (r) {
                        return $.extend(r, { url: 'http://twitter.com/' + r.from_user + '/statuses/' + r.id, title: $('<div/>').append(r.text).text() });
                    });

                    ProcessData(results, this);
                }
            }
        });

    if (source.searchFormat == 'google') {

        //build parameters
        var params = { q: val, v: '1.0', start: source.maxCount * (page - 1) };
        if (source.restrictLang)
            params.lr = lang;
        if (source.append) {
            params.q += source.append + googleExcludeAppend;
            params.rsz = 'large';
        } else {
            params.cx = source.cse;
            params.rsz = 'filtered_cse';
        }

        $.ajax({
            url: 'http://ajax.googleapis.com/ajax/services/search/web',
            data: params,
            context: { sourceIndex: sourceIndex, query: val },
            dataType: 'jsonp',
            success: function (data) {
                if (data.responseStatus != 200) { appendError(this.sourceIndex); return; }

                //normalize content and title as plain text
                $.each(data.responseData.results, function (cnt, item) {
                    item.content = $('<div/>').append(item.content).text();
                    //titlenoformatting from google is still html with encoded ' characters
                    item.title = $('<div/>').append(item.titleNoFormatting).text();
                });

                ProcessData(data.responseData.results, this);
            }
        });
    }

    if (source.searchFormat == 'Clinical')
        $.ajax({
            url: 'http://query.yahooapis.com/v1/public/yql',
            data: {
                format: 'json',
                q: 'select * from xml where url=@url',
                url: 'http://clinicaltrials.gov/search?displayxml=true&count=' + source.maxCount
                        + '&start=' + (((page - 1) * source.maxCount) + 1) + '&term=' + escape(val)
            },
            context: { sourceIndex: sourceIndex, query: val },
            dataType: 'jsonp',
            success: function (data) {
                if (data.error || data.query == null)
                    appendError(this.sourceIndex);
                else
                    ProcessData(data.query.count == 0 || data.query.results.search_results.count == 0 ? [] :
                                data.query.results.search_results.clinical_study, this);
            }
        });

    if (source.searchFormat == 'medtango') {
        var refID = $('#referenceID').val();
        if (refID)
            eval('refID = ' + refID + '.' + source.name + ';');

        $.ajax({
            url: '/Home/SearchMedTango' + source.name,
            data: { searchText: val, count: source.maxCount, page: page, trackSearch: bTrackSearch, referenceID: refID },
            type: 'POST',
            context: { sourceIndex: sourceIndex, query: val },
            success: function (data) { ProcessData(data, this); },
            error: function () { appendError(this.sourceIndex); }
        });
        searchTracked = true;
    }
}

//primary method that processes data coming into the browser
function ProcessData(results, context) {
    var source = sources[context.sourceIndex];
    var query = context.query;
    var currentSearch = $('#resultsDiv').data('search');
    var currentPage = $('#resultsDiv').data('pages')[context.sourceIndex];

    //if they ran another search since this one was called
    if (query != currentSearch)
        return;

    //translate results
    if (lang != 'en' && source.translate && !context.translated) {
        $.translate($.map(results,
            function (result) {
                return source.searchFormat == "Clinical" ? [result.title, result.condition_summary, result.status.content] : [result.title, result.content];
            }), lang,
            {
                complete: function (translations) {
                    $.each(results, function (i, result) {
                        result.url = 'http://translate.google.com/translate?js=y&sl=auto&tl=' + lang + '&u=' + escape(result.url);
                        if (source.searchFormat == "Clinical")
                        { result.title = translations[i * 3]; result.condition_summary = translations[i * 3 + 1]; result.status.content = translations[i * 3 + 2]; }
                        else { result.title = translations[i * 2]; result.content = translations[i * 2 + 1]; }
                    });

                    //call back the process method, telling it not to translate again
                    context.translated = true;
                    ProcessData(results, context);
                },
                error: function () { appendError(context.sourceIndex); }
            });
        return;
    }

    _ProcessData(results, context);
}


function tooltipGeneric(result) {
    var title = $('<div/>').text(result.title).addClass('tooltipTitle');
    var description = $('<div/>').text(result.content).addClass('tooltipDescription');
    return title.add(description);
}

function tooltipTwitter(result) {
    var title = $('<div/>').text(result.title).addClass('tooltipTitle');
    var description = $('<div/>').addClass('tooltipDescription')
                            .append($('<img/>').attr('src', result.profile_image_url).add('<br/>'))
                            .appendText(twitterTooltip.author + ': ' + result.from_user).append('<br/>')
                            .appendText(twitterTooltip.date + ': ' + new Date(result.created_at).toLocaleString());
    return title.add(description);
}

function tooltipDrugs(result) {
    var title = $('<div/>').text(result.title).addClass('tooltipTitle');
    var description = $('<div/>').html(result.content).addClass('tooltipDescription');
    return title.add(description);
}

function tooltipInteractions(result) {
    var title = $('<div/>').text(result.drugTitle).addClass('tooltipTitle');
    var description = $('<div/>').html(result.drugContent).addClass('tooltipDescription');
    $('<div/>').html('<br/><b>' + interactionTypes[result.InteractionTypeID.toString()] + '</b><br/>' + result.InteractionXML)
        .appendTo(description);
    return title.add(description);
}

function tooltipDisease(result) {
    var title = $('<div/>').text(result.title).addClass('tooltipTitle');
    var subTitle = $('<div/>').text(diseaseTooltip.gender + ': ' + result.Gender).addClass('tooltipSubtitle');
    var description = $('<div style="text-align: left;"/>').html(result.Description).addClass('tooltipDescription');
    return title.add(subTitle).add(description);
}

function tooltipDailyMed(result) {
    var title = $('<div/>').text(result.title).addClass('tooltipTitle');
    var subTitle = $('<div/>').text(result.Category).addClass('tooltipSubtitle');
    var description = $('<div/>').addClass('tooltipDescription');
    if (result.DosageFormIDs)
        $('<div/>').text(dailymedTooltip.dosageForms + ': ' +
            $.map(result.DosageFormIDs.split(','), function (id) { return dosageForms[id]; }).join('; ')).appendTo(description);
    if (result.DEADrugSchedule)
        $('<div/>').text(dailymedTooltip.deaSchedule + ': ' + result.DEADrugSchedule).appendTo(description);
    if (result.MarketingStatus)
        $('<div/>').text(dailymedTooltip.marketingStatus + ': ' + result.MarketingStatus).appendTo(description);
    return title.add(subTitle).add(description);
}

/*function tooltipClinical(result) {
var title = $('<div/>').text(result.title).addClass('tooltipTitle');
var subTitle = $('<div/>').text(clinicalTooltipText.condition + ': ' + result.condition_summary).addClass('tooltipSubtitle');
var description = $('<div/>').html(clinicalTooltipText.status + ': ' + result.status.content +
'<br/>' + clinicalTooltipText.last_changed + ': ' + result.last_changed).addClass('tooltipDescription');

return title.add(subTitle).add(description);
}*/

//add appendText method to shortcut createTextNode
(function ($) { $.fn.extend({ appendText: function (e) { return typeof e == 'string' ? this.append(document.createTextNode(e)) : this; } }); })(jQuery);