function generateCssTemplateFromText(){
    var source, i, res, alreadySelector, selector, charset, declareCharset;
    var selectorIndex, properties, excludeTags, options;
    // 除外タグ設定
    source = jQuery('textarea#source').val();
    source = removeScriptTags(source);
    putSourceIframe(source);
    charset = jQuery('select#charset').val();
    options = {
        cutElementName: jQuery('input#cutElementName').attr('checked'),
        cutParentNodes: jQuery('input#cutParentNodes').attr('checked'),
        excludeTags: jQuery('input#excludeTags').val().replace(/[ 　]/g, '').split(",")
    };
    if (charset === '') {
        charset = 'utf-8';
    }
    declareCharset = "@charset \"" + charset + "\"\;\n";
    alreadySelector = [];
    elements = getElementsIframe();
    properties = '';
    selectorIndex = '';
    for (i in elements) {
        if (elements[i].nodeType === 1) {
            if (jQuery.inArray(elements[i].tagName.toLowerCase(), options.excludeTags) != -1) {
                continue;
            }
            selector = generateSelector(elements[i], options);
            if (jQuery.inArray(selector, alreadySelector) != -1) {
                continue;
            }
            if (elements[i].tagName.toLowerCase() === 'div' && elements[i].id !== '') {
                properties = properties
                    + "/* =========================================================\n"
                    + elements[i].id + "\n"
                    + "========================================================= */\n";
                selectorIndex = selectorIndex + generateSelectorIndexItem(elements[i]) + "\n";
            }
            properties = properties + selector + " {\n}\n\n";
            alreadySelector.push(selector);
        }
    }
    selectorIndex = "/* ///////////////////////////////////////////////////////////////////\n\n"
        + selectorIndex + "\n"
        + "/////////////////////////////////////////////////////////////////// */\n";
    res = declareCharset + "\n" + selectorIndex + "\n" + jQuery('#alreadySelector').val() + "\n" + properties;
    jQuery('textarea#result').val(res);
    downloadCssFile();
}

function generateSelectorIndexItem(element) {
    var indexItem, parentDivs, i;
    parentDivs = jQuery(element).parents('div[id]');
    indexItem = '';
    for (i = 0; i < parentDivs.length; i++) {
        indexItem = indexItem + "\t";
    }
    indexItem = indexItem + "[" + element.id + "]";
    return indexItem;
}

function removeScriptTags(source) {
    return source.replace(/<script(.|\n)*?<\/script>/g, '');
}

function getElementsIframe(){
    return jQuery('body *', jQuery('iframe#sourceHtml').contents()[0]);
}

function putSourceIframe(source){
    jQuery('body', jQuery('iframe#sourceHtml').contents()[0]).html(source);
}

function generateSelector(el, options){
    var ancestors, selector;

    selector = generateSimpleSelector(el, options);

    ancestors = jQuery.makeArray(jQuery(el).parents());
    for (i in ancestors) {
        // idのある要素の親は省略するオプション
        if (options.cutParentNodes) {
            if (selector.indexOf('#') != -1) {
                break;
            }
        }
        if (jQuery.inArray(ancestors[i].tagName.toLowerCase(), options.excludeTags) != -1) {
            continue;
        }
        
        if (jQuery.inArray(ancestors[i].tagName, ['BODY', 'HTML']) == -1) {
            selector = generateSimpleSelector(ancestors[i], options) + ' ' + selector;
            selector = selector.replace(/^\s+|\s+$/g, "");
        }
    }
    return selector;
}

function downloadCssFile(){
    // http://piro.sakura.ne.jp/latest/blosxom/webtech/javascript/2005-10-05_download.htm
    var text;
    text = jQuery('textarea#result').val();
    jQuery('a#saveCss').attr('href', 'data:application/octet-stream,'+encodeURIComponent(text));
}

// 単純な要素セレクタを取得する
// 要素名 + (id または class の一番目)
function generateSimpleSelector(el, options){
    var selector, id, classes;

    id = jQuery(el).attr('id');
    classes = el.className;
    // idがある要素の要素名を省略するオプション
    if (options.cutElementName && (id !== '' || classes !== '')) {
        selector = '';
    } else {
    	selector = el.tagName.toLowerCase();
    }

    if (id) {
        selector = selector + '#' + id;
    } else if (classes) {
        selector = selector + '.' + classes.split(' ')[0];
    }
    return selector;
}

/**
 * 生成ボタンイベント
 */
function attachGenerateEvent(){
    jQuery('input#generateFromText').click(generateCssTemplateFromText);
}

// CSS生成結果を一発選択
function attachResultSelect(){
    jQuery('textarea#result').bind('click', function(){
        $(this).select();
        return false;
    });
}

/**
 * サンプルコードをHTMLソースフィールドに貼り付け
 */
function attachPutSample(){
    jQuery('#putSample1').click(function(){ jQuery('#source').val(jQuery('#sample1').val()); });
    jQuery('#putSample2').click(function(){ jQuery('#source').val(jQuery('#sample2').val()); });
    jQuery('#putSample3').click(function(){ jQuery('#source').val(jQuery('#sample3').val()); });
}

/**
 * オプションの表示切り替え
 */
function toggleOption(){
    jQuery('input#toggleOption').toggle(
        function(){
            jQuery('div#option').hide();
        },
        function(){
            jQuery('div#option').show();
        }
    ).click();
}

jQuery(document).ready(attachGenerateEvent);
jQuery(document).ready(attachPutSample);
jQuery(document).ready(toggleOption);
jQuery(document).ready(attachResultSelect);

