/*______________________________________

  mizuyariTategaki #090302b [version 0.05]
  
  Copyright (C) 2009 mizuyari All rights reserved.
  Script written by Mahiro Komura <mahirok@mizuyari.jp>
  http://mizuyari.jp/
______________________________________*/

function mizuyariTategakiInit() { // #090302b
    var tategakiCSS = "/shared/modules/mizuyari-tategaki/mizuyari-tategaki.css";
    var tategakiElements = getElementsByClassName('mizuyari-tategaki');
    mizuyari.addCSS(tategakiCSS);
    for (var i=0; i<tategakiElements.length; i++) {
        tategakiElements[i] = new mizuyariTategaki(tategakiElements[i]);
    }
}

function mizuyariTategaki(element) { // #090302b
    this.parentElmt = element;
    this.lines = 0;
    this.cols = 0;
    this.pages = 0;
    this.charHeight = 22;
    this.charsPerLine = 20;
    this.lineHeight = 35;
    this.linesPerPage = 20;
    this.pageHeight = 677;
    this.nodecnt = 0; // debug
    this.baseImagePath = "/shared/modules/mizuyari-tategaki/images/";
    this.elementStyles = {
        "P"  : { "lineSpacing" : 1, "textIndent" : 1 },
        "A"  : { "lineSpacing" : 0, "textIndent" : 0 },
        "H1" : { "lineSpacing" : 1, "textIndent" : 3 },
        "H2" : { "lineSpacing" : 1, "textIndent" : 1 },
        "H3" : { "lineSpacing" : 1, "textIndent" : 1 },
        "H4" : { "lineSpacing" : 1, "textIndent" : 1 },
        "H5" : { "lineSpacing" : 1, "textIndent" : 1 },
        "H6" : { "lineSpacing" : 1, "textIndent" : 1 }
    }
    this.init();
}

mizuyariTategaki.prototype = {
    init : function() { // #090302b
        this.applyNewMarkup(this.parentElmt);
        if (mizuyari.ua.isWinIE60) this.parentElmt.style.height = ((this.pages + 1) * 677) + "px";
        this.parentElmt.style.minHeight = ((this.pages + 1) * this.pageHeight) + "px";
    },
    
    applyNewMarkup : function (node) { // #090302b
     for (var i=0; i<node.childNodes.length; i++) {
        var currentNode = node.childNodes[i];
        if (currentNode.nodeType == 3) {
            if (currentNode.nodeValue.match(/ *\n$/)) continue;
            var newNodes = this.applySpanElmtToText(currentNode);
            // replaceNodes
            var j = 0;
            var nodesLength = newNodes.childNodes.length;
            while (newNodes.firstChild) {
                var vAlign = (mizuyari.containsClass(node, "author")) ? "bottom" : "top" 
                this.setTategakiCharPosition(newNodes.firstChild, j, nodesLength, vAlign);
                node.insertBefore(newNodes.firstChild, currentNode);                    
                i++; j++;
            }
            node.removeChild(currentNode);
            i--;
            // line spacing
            if (i == node.childNodes.length -1) this.lineSpacing(node.nodeName);
        }
        if (currentNode.nodeType == 1) {
            this.textIndent(currentNode.nodeName);
            if (currentNode.nodeName == "BR" &&
            (this.cols != 0 || this.cols >= this.charsPerLine-1)) this.lineBreak();
            if (currentNode.hasChildNodes) this.applyNewMarkup(currentNode);
        }
     }
    },

    setTategakiCharPosition : function (element, charIndex, totalNodes, vAlign) { // #090302b
     var char;
     if (element.firstChild.nodeName == "IMG") {
        char = element.firstChild.alt;
     } else {
        char = (mizuyari.ua.isWinIE) ? element.innerText : element.textContent;
     }
     if (char == "。" || char == "、") mizuyari.addClass(element, "punctuation");
     this.kinsokuShori(char, charIndex);

     element.style.top = (vAlign == "top") ?
      (this.pages * this.pageHeight) + (this.cols * this.charHeight) + 'px' :
      (this.pages * this.pageHeight) + ((this.charsPerLine - totalNodes + -1 + charIndex) * this.charHeight) + 'px';
     element.style.right = (this.lines * this.lineHeight) + 'px';
     // element.id = "ln_" + this.lines + "col_" + this.cols;
     this.cols++;

     if (this.cols >= this.charsPerLine) this.lineBreak();
    },
    
    kinsokuShori : function (char, charIndex) { // #090302b
     if (charIndex != 0 && this.cols == 0 && this.kinsokuTop(char)) {
        if (this.lines == 0) {
            this.pages--; this.lines = this.charsPerLine-1;
        } else {
            this.lines--;
        }
        this.cols = this.charsPerLine;
     } else if (this.cols == this.charsPerLine-1 && this.kinsokuBottom(char)) {
      this.lineBreak();
     }
    },

    kinsokuBottom : function (char) { // #090302b
        var kinsokuBottomChars = "‘“〈《「『【〔［｛（";
        return kinsokuBottomChars.indexOf(char) != -1;
    },

    kinsokuTop : function (char) { // #090302b
        var kinzokuTopChars = "’”、。〉》」』】〕］｝）ゝゞヽヾ々・：；！？ー　";
        return kinzokuTopChars.indexOf(char) != -1;
    },
    
    shitayose : function () { // #090302b
    },

    textIndent : function (nodeName) { // #090302b
        this.cols += (!this.elementStyles[nodeName]) ? 0 : this.elementStyles[nodeName].textIndent;
    },
    
    lineSpacing : function (nodeName) { // #090302b
        var lineSpacing = (!this.elementStyles[nodeName]) ? 1 : this.elementStyles[nodeName].lineSpacing;
        if (lineSpacing > 0) {
            this.lines += lineSpacing;
            if ((this.cols == 0)) this.lines--;
            if (this.elementStyles[nodeName].lineSpacing) this.cols = 0;
            if (this.lines >= this.linesPerPage) { this.nextPage(); }
        }
    },

    lineBreak : function () { // #090302b
        this.lines++; this.cols=0;
        if (this.lines >= this.charsPerLine) { this.nextPage(); }
    },

    nextPage : function () { // #090302b
        this.pages++;
        this.lines = 0;
    },

    applySpanElmtToText : function (textNode) { // #090302b
        var container = mizuyari.elementFactory("DIV");
        var textArray = textNode.nodeValue.split("");
            textArray.remove("\n");
        for (var i=0; i<textArray.length; i++) {
        textArray[i] = this.markupChar(textArray[i]);
        }
        container.innerHTML = textArray.join("");
        return container;
    },
    
    markupChar : function(char) { // #090302b
        var specialChars = "〈《「『【〔［｛（〉》」』】〕］｝）：；ー…‥～〜";
        if (specialChars.indexOf(char) != -1) {
            return (mizuyari.ua.isFirefox && typeof(Worker) != "undefined" ||
            mizuyari.ua.isKHTML && document.compatMode || mizuyari.ua.isWinIE) ?
                '<span class="rotate90">' + char + '<\/span>' :
                '<span><img src="' + this.baseImagePath + 'chars/' + 
                EscapeUnicode(char).substring(1) + '.png" alt="' + char + '" /><\/span>';
        } 
        return '<span>' + char + '<\/span>';
    }

}

mizuyari.addOnLoadEvent(mizuyariTategakiInit);