' Text2Phone
' 애니콜에서 파일뷰어로 텍스트롤 읽고자 하는 사용자들을 위해 만든 도구
' 기능 : 애니콜 파일뷰어에서 보기 좋도록 텍스트 폭을 고정시키고.. 페이지 넘기기에 좋게 한 화면에 나오지 않는 아래 부분은 빈줄 처리..
' 제작 : 박종호 pjhplace@naver.com
' 언어 : PowerBasic

#COMPILE EXE
#DIM ALL
#INCLUDE "Win32API.INC"
#RESOURCE "Resources.pbr" ' 아이콘 정보

$AppTitle = "Text2Phone v1.0" ' 프로그램 명칭

GLOBAL hDlg AS DWORD ' 대화상자 핸들
GLOBAL lResult AS LONG ' 대화상자 결과값

%TextBox1 = 101 ' 텍스트박스 식별 번호
%TextBox2 = 102 ' 텍스트박스 식별 번호
%TextBox3 = 103 ' 텍스트박스 식별 번호

%Label1 = 110

$CriteriaChar = CHR$(128) ' 문자 검사시 한글과 영문을 구분하기 위한 기준값

GLOBAL TempStr AS STRING, TempStr2 AS STRING ' 임시 문자열 변수
GLOBAL Text1Value AS LONG, Text2Value AS LONG, Text3Value AS LONG ' 텍스트 박스의 값을 보관할 변수

DECLARE CALLBACK FUNCTION DialogWindow() AS LONG ' 대화상자의 버튼이 눌려졌을 때 호출되는 함수

FUNCTION PBMAIN () AS LONG

    REGISTER Temp1 AS LONG, Temp2 AS LONG ' 레지스트리 변수
    LOCAL DialogReCounter AS LONG ' 대화상자가 처음 호출인지, 재호출인지 판단을 위해 사용

    DO
        INCR DialogReCounter ' 1씩 증가

        DIALOG FONT "Gulim", 9
        DIALOG NEW PIXELS, 0, $AppTitle, , ,460, 216, &H084C000D4&, 0 TO hDlg ' 대화상자 생성
        CONTROL ADD LABEL, hDlg, %Label1, "아래의 값은 파일뷰어에서 읽기 좋은 정도로 확대한 상태를 기준으로 합니다.", 10, 10, 440, 20 ' 라벨 추가
        CONTROL SET COLOR hDlg, %Label1, %BLUE, -1&
        CONTROL ADD LABEL, hDlg, 0, "가로 글자수(바이트 단위)", 75, 36, 320, 20 ' 라벨 추가
        CONTROL ADD LABEL, hDlg, 0, "한 화면에 표시되는 라인수(액정에 들어가는 줄 수)", 75, 62, 440, 20
        CONTROL ADD LABEL, hDlg, 0, "한 페이지 라인수(파일뷰어에서 한 페이지 줄 수)", 75, 88, 440, 20

        CONTROL ADD LABEL, hDlg, 0, "현재 폴더에 있는 모든 텍스트 파일을 변환합니다. 결과는 하부폴더에 저장", 10, 136, 440, 20
        CONTROL ADD LABEL, hDlg, 0, "앞쪽에 나오는 공백은 무시, 연속된 공백은 1개로 처리합니다.", 10, 156, 440, 20
        CONTROL ADD LABEL, hDlg, 0, "제작 : 박종호 pjhplace@naver.com / 추가적인 기능 추가는 없을 예정", 10, 176, 440, 20
        CONTROL ADD LABEL, hDlg, 0, "이 프로그램으로 인해 발생한 사고 및 손실에 대해 책임지지 않습니다.", 10, 196, 440, 20

        CONTROL ADD BUTTON, hDlg, %IDOK, "확인", 375, 36, 75, 30, %WS_TABSTOP ' 버튼 추가
        CONTROL ADD BUTTON, hDlg, %IDCANCEL, "취소", 375, 71, 75, 30, %WS_TABSTOP

        IF DialogReCounter = 1 THEN ' 대화상자 처음 호출시
            CONTROL ADD TEXTBOX, hDlg, %TextBox1, "40", 10,34,55,16 ' 텍스트 박스 추가
            CONTROL ADD TEXTBOX, hDlg, %TextBox2, "16", 10,60,55,16
            CONTROL ADD TEXTBOX, hDlg, %TextBox3, "75", 10,86,55,16
        ELSE ' 입력값 이상으로 대화상자 재호출시
            CONTROL ADD TEXTBOX, hDlg, %TextBox1, LTRIM$(STR$(Text1Value)), 10,34,55,16
            CONTROL ADD TEXTBOX, hDlg, %TextBox2, LTRIM$(STR$(Text2Value)), 10,60,55,16
            CONTROL ADD TEXTBOX, hDlg, %TextBox3, LTRIM$(STR$(Text3Value)), 10,86,55,16
        END IF

        CONTROL SET FOCUS hDlg, %TextBox1 ' 텍스트박스1번에 포커스

        DIALOG SHOW MODAL hDlg, CALL DialogWindow() TO lResult ' 모달로 대화상자 호출

        SELECT CASE lResult ' 이벤트 발생한 컨트롤 고유ID
            CASE %IDOK ' OK 버튼이 눌려졌을 때
                IF Text1Value < 12 THEN
                    MSGBOX "가로 글자수는 12자 이상이어야 합니다.    ", %MB_ICONINFORMATION, $AppTitle
                    ITERATE DO ' 대화상자 재호출
                END IF
                IF Text1Value > 300 THEN
                    MSGBOX "가로 글자수가 제한 300자를 초과하고 있습니다.    ", %MB_ICONINFORMATION, $AppTitle
                    ITERATE DO ' 대화상자 재호출
                END IF
                IF Text2Value < 5 THEN
                    MSGBOX "한 화면에 표시되는 라인수는 5줄 이상이어야 합니다.    ", %MB_ICONINFORMATION, $AppTitle
                    ITERATE DO ' 대화상자 재호출
                END IF
                IF Text2Value > Text3Value THEN
                    MSGBOX "한 화면에 표시되는 라인수가 한 페이지 라인수보다 작거나 같아야 합니다.    ", %MB_ICONINFORMATION, $AppTitle
                    ITERATE DO ' 대화상자 재호출
                END IF
                IF Text3Value > 300 THEN
                    MSGBOX "한 페이지 라인수가 제한 300줄을 넘어가고 있습니다.    ", %MB_ICONINFORMATION, $AppTitle
                    ITERATE DO ' 대화상자 재호출
                END IF
                EXIT DO ' 루프를 벗어나 본과정으로 넘어감
            CASE %IDCANCEL ' 취소 버튼이 눌려졌을 때
                EXIT FUNCTION ' 프로그램 종료
        END SELECT
    LOOP

    ' 본격 처리

    DIM Files(1 TO 100) AS STRING
    LOCAL FilesCounter AS LONG
    LOCAL CurPath AS STRING
    LOCAL SubDir AS STRING

    CurPath = CURDIR$
    IF RIGHT$(CurPath, 1) = "\" THEN CurPath = LEFT$(CurPath, LEN(CurPath) - 1)

    TempStr = DIR$(CurPath & "\*.txt")
    DO UNTIL TempStr = ""
        INCR FilesCounter
        Files(FilesCounter) = TempStr
        IF FilesCounter = 100 THEN
            MSGBOX "파일수가 100개를 초과하여 앞쪽 100개만 변환하겠습니다.    ", %MB_ICONINFORMATION, $AppTitle
            EXIT DO
        END IF
        TempStr = DIR$
    LOOP

    IF FilesCounter = 0 THEN
        MSGBOX "현재 폴더에 작업할 텍스트 파일이 없습니다.    ", %MB_ICONINFORMATION, $AppTitle
        EXIT FUNCTION
    END IF

    ' 서브 폴더 만들기

    DO
        SubDir = TIME$
        REPLACE ":" WITH "-" IN SubDir
        SubDir = SubDir & "-" & LTRIM$(STR$(INT(TIMER)))
        IF DIR$(CurPath & "\" & SubDir, %SUBDIR) = "" THEN EXIT DO
    LOOP

    MKDIR CurPath & "\" & SubDir

    %MaxStrLen = 10000

    LOCAL InputLine AS STRING * %MaxStrLen, OutputLine AS STRING * 301
    LOCAL InputLineLen AS LONG
    LOCAL InputLinePos AS LONG, OutputLinePos AS LONG

    LOCAL CurrentChar AS STRING*1

    LOCAL ConsecutiveBlankLines AS LONG ' 이어지는 빈줄을 한 줄로 처리하기 위해서
    LOCAL ConsecutiveBlanks AS LONG ' 이어지는 빈칸을 한 글자로 처리하기 위해서
    LOCAL LinesFromTop AS LONG ' 현재 페이지에서 기록한 줄 수, 액정 라인을 넘어가면 페이지의 나머지는 빈줄로 채운다.

    LOCAL OutputRealWidth AS LONG ' 양쪽 정렬을 위해 실제 출력라인 글자수가 몇 자인가 확인
    LOCAL LatestBlankPos AS LONG ' 가장 뒷쪽 중간에 삽입된 빈칸 위치

    DIALOG FONT "Gulim", 9
    DIALOG NEW PIXELS, 0, $AppTitle, , ,420, 30, &H084C000D4&, 0 TO hDlg ' 대화상자 생성
    CONTROL ADD LABEL, hDlg, %Label1, "", 10, 10, 400, 20 ' 라벨 추가

    DIALOG SHOW MODELESS hDlg

    ' 파일 각개 검사
    FOR Temp1 = 1 TO FilesCounter

        CONTROL SET TEXT hDlg, %Label1, LTRIM$(STR$(Temp1)) & "/" & LTRIM$(STR$(FilesCounter)) & " - " & Files(Temp1)

        OPEN CurPath & "\" & Files(Temp1) FOR INPUT AS #1
        OPEN CurPath & "\" & SubDir & "\" & Files(Temp1) FOR OUTPUT AS #2

        OutputLine = "" : OutputLinePos = 0
        LinesFromTop = 0
        ConsecutiveBlankLines = 0
        ConsecutiveBlanks = 0

        DO UNTIL EOF(1)
            LINE INPUT #1, TempStr
            TempStr = TRIM$(TempStr)

            IF TempStr = "" THEN ' 빈줄일 경우
                INCR ConsecutiveBlankLines
                IF ConsecutiveBlankLines > 1 THEN ITERATE DO
                ' 빈줄이 처음 나왔을 때만 출력에 한 줄 삽입
                IF LinesFromTop = 0 THEN ITERATE DO

                ' 페이지의 첫 줄이 아닐 때만 빈줄을 집어넣는다.
                PRINT #2, ""
                INCR LinesFromTop

                IF LinesFromTop < Text2Value THEN ITERATE DO
                ' 한 화면이 다 차면 나머지는 빈줄로 채움
                IF Text2Value = Text3Value THEN ITERATE DO
                ' 빈줄 채우기
                FOR Temp2 = 1 TO Text3Value - Text2Value
                    PRINT #2, ""
                NEXT Temp2
                LinesFromTop = 0
                ConsecutiveBlankLines = 0
                ITERATE DO
            END IF

            ' 빈줄이 아닐 경우
            ConsecutiveBlankLines = 0
            InputLineLen = LEN(TempStr)
            InputLine = TempStr
            InputLinePos = 0

            DO
                INCR InputLinePos
                CurrentChar = MID$(InputLine, InputLinePos, 1)

                IF CurrentChar < $CriteriaChar THEN ' 알파벳
                    IF CurrentChar = " " THEN
                        INCR ConsecutiveBlanks
                        IF ConsecutiveBlanks = 1 THEN
                            IF OutputLinePos > 0 THEN
                                INCR OutputLinePos
                                MID$(OutputLine, OutputLinePos, 1) = " "
                            END IF
                        END IF
                    ELSE
                        ConsecutiveBlanks = 0
                        INCR OutputLinePos
                        MID$(OutputLine, OutputLinePos, 1) = CurrentChar
                    END IF
                ELSE ' 한글, 한자, 특수문자 등..
                    ConsecutiveBlanks = 0
                    INCR OutputLinePos
                    MID$(OutputLine, OutputLinePos, 1) = CurrentChar
                    INCR InputLinePos
                    CurrentChar = MID$(InputLine, InputLinePos, 1)
                    INCR OutputLinePos
                    MID$(OutputLine, OutputLinePos, 1) = CurrentChar
                END IF

                IF OutputLinePos >= Text1Value-1 OR InputLinePos >= InputLineLen THEN ' 화면폭 글자수를 넘어가거나 원본 한줄이 끝나면 기록
                    FOR Temp2 = Text1Value TO 1 STEP -1
                        IF MID$(OutputLine, Temp2, 1) <> " " THEN EXIT FOR
                    NEXT Temp2

                    OutputRealWidth = Temp2
                    IF OutputRealWidth = 0 THEN GOTO NextProcess

                    IF OutputRealWidth > 3 AND OutputRealWidth < Text1Value THEN
                        FOR Temp2 = OutputRealWidth - 1 TO 2 STEP -1
                            IF MID$(OutputLine, Temp2, 1) = " " THEN EXIT FOR
                        NEXT Temp2

                        IF Temp2 >= 2 THEN
                            OutputLine = LEFT$(OutputLine, Temp2) & SPACE$(Text1Value - OutputRealWidth) & MID$(OutputLine, Temp2 + 1, OutputRealWidth - Temp2)
                            OutputRealWidth = Text1Value
                        END IF
                    END IF

                    PRINT #2, LEFT$(OutputLine, OutputRealWidth)
                    INCR LinesFromTop
                    OutputLinePos = 0
                    OutputLine = ""
                END IF

NextProcess:

                IF LinesFromTop = Text2Value THEN ' 한 화면이 다 차면 페이지의 나머지는 빈줄로 채움
                    IF Text2Value < Text3Value THEN
                        FOR Temp2 = 1 TO Text3Value - Text2Value
                            PRINT #2, ""
                        NEXT Temp2
                        LinesFromTop = 0
                        ConsecutiveBlankLines = 0
                    END IF
                END IF

                IF InputLinePos >= InputLineLen THEN EXIT DO ' 한 줄 검사 완료시 새로운 문장으로 넘어감

            LOOP ' 한 문장 검사 루프

        LOOP ' 파일 개별 검사 루프

        CLOSE

    NEXT Temp1

    DIALOG END hDlg

END FUNCTION

CALLBACK FUNCTION DialogWindow() AS LONG
    IF CBMSG = %WM_COMMAND THEN
        SELECT CASE CBCTL ' 컨트롤 분류
            CASE %IDOK TO %IDCANCEL ' 버튼일 경우
                IF CBCTLMSG = %BN_CLICKED THEN ' 버튼이 클릭됐을 때
                    ' 텍스트값 구하기
                    CONTROL GET TEXT hDlg, %TextBox1 TO TempStr
                    Text1Value = VAL(TempStr)

                    CONTROL GET TEXT hDlg, %TextBox2 TO TempStr
                    Text2Value = VAL(TempStr)

                    CONTROL GET TEXT hDlg, %TextBox3 TO TempStr
                    Text3Value = VAL(TempStr)

                    DIALOG END CBHNDL, CBCTL ' 대화상자 종료하면서 이벤트 발생한 컨트롤ID 반환
                    FUNCTION = 1 ' 이벤트 정상 처리 알림
                END IF
        END SELECT
    END IF
END FUNCTION
